fixing missing upcast

This commit is contained in:
Jakub Doka 2024-10-27 18:04:50 +01:00
parent 83d3fb4919
commit 5926f69e6c
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
2 changed files with 28 additions and 16 deletions

View file

@ -4,7 +4,7 @@ use {
son, son,
}, },
alloc::{string::String, vec::Vec}, alloc::{string::String, vec::Vec},
core::{fmt::Write, num::NonZeroUsize}, core::{fmt::Write, num::NonZeroUsize, ops::Deref},
hashbrown::hash_map, hashbrown::hash_map,
std::{ std::{
collections::VecDeque, collections::VecDeque,
@ -77,7 +77,9 @@ pub fn run_compiler(root_file: &str, options: Options, out: &mut Vec<u8>) -> std
fn format_ast(ast: parser::Ast) -> std::io::Result<()> { fn format_ast(ast: parser::Ast) -> std::io::Result<()> {
let mut output = String::new(); let mut output = String::new();
write!(output, "{ast}").unwrap(); write!(output, "{ast}").unwrap();
std::fs::write(&*ast.path, output)?; if ast.file.deref() != output.as_str() {
std::fs::write(&*ast.path, output)?;
}
Ok(()) Ok(())
} }

View file

@ -2151,15 +2151,23 @@ impl<'a> Codegen<'a> {
); );
} }
if self.tys.size_of(val.ty) <= self.tys.size_of(ty) { match self.tys.size_of(val.ty).cmp(&self.tys.size_of(ty)) {
val.ty = ty; core::cmp::Ordering::Less => {
return Some(val); self.extend(&mut val, ty);
Some(val)
}
core::cmp::Ordering::Equal => Some(val.ty(ty)),
core::cmp::Ordering::Greater => {
let value = (1i64 << (self.tys.size_of(ty) * 8)) - 1;
let mask = self.ci.nodes.new_node_nop(val.ty, Kind::CInt { value }, [VOID]);
let inps = [VOID, val.id, mask];
Some(self.ci.nodes.new_node_lit(
ty,
Kind::BinOp { op: TokenKind::Band },
inps,
))
}
} }
let value = (1i64 << (self.tys.size_of(ty) * 8)) - 1;
let mask = self.ci.nodes.new_node_nop(val.ty, Kind::CInt { value }, [VOID]);
let inps = [VOID, val.id, mask];
Some(self.ci.nodes.new_node_lit(ty, Kind::BinOp { op: TokenKind::Band }, inps))
} }
Expr::Directive { name: "as", args: [ty, expr], .. } => { Expr::Directive { name: "as", args: [ty, expr], .. } => {
let ty = self.ty(ty); let ty = self.ty(ty);
@ -3156,9 +3164,7 @@ impl<'a> Codegen<'a> {
}; };
if let Some(oper) = to_correct { if let Some(oper) = to_correct {
self.strip_ptr(oper); self.extend(oper, upcasted);
oper.ty = upcasted;
oper.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, oper.id]);
if matches!(op, TokenKind::Add | TokenKind::Sub) if matches!(op, TokenKind::Add | TokenKind::Sub)
&& let Some(elem) = self.tys.base_of(upcasted) && let Some(elem) = self.tys.base_of(upcasted)
{ {
@ -3205,9 +3211,7 @@ impl<'a> Codegen<'a> {
self.ty_display(src.ty), self.ty_display(src.ty),
self.ty_display(upcasted) self.ty_display(upcasted)
); );
self.strip_ptr(src); self.extend(src, upcasted);
src.ty = upcasted;
src.id = self.ci.nodes.new_node(upcasted, Kind::Extend, [VOID, src.id]);
} }
true true
} else { } else {
@ -3218,6 +3222,12 @@ impl<'a> Codegen<'a> {
} }
} }
fn extend(&mut self, value: &mut Value, to: ty::Id) {
self.strip_ptr(value);
value.ty = to;
value.id = self.ci.nodes.new_node(to, Kind::Extend, [VOID, value.id]);
}
#[track_caller] #[track_caller]
fn report(&self, pos: Pos, msg: impl core::fmt::Display) { fn report(&self, pos: Pos, msg: impl core::fmt::Display) {
let mut buf = self.errors.borrow_mut(); let mut buf = self.errors.borrow_mut();