properly type checking, null checks are fixed

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2024-12-16 23:32:08 +01:00
parent 1ca9529302
commit e65c72e19f
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
2 changed files with 29 additions and 26 deletions

View file

@ -937,8 +937,14 @@ StructB := struct {g: ^uint, c: StructC}
StructC := struct {c: uint} StructC := struct {c: uint}
some_index := fn(): ?uint return 0
heap := [u8].(0, 1, 2)
optionala := fn(): ?StructA { optionala := fn(): ?StructA {
return .(.(&0, .(1)), &0, 0) i := some_index()
if i == null die
return .(.(&0, .(1)), &0, heap[i])
} }
Struct := struct {inner: uint} Struct := struct {inner: uint}

View file

@ -28,11 +28,9 @@ use {
fmt::{self, Debug, Display, Write}, fmt::{self, Debug, Display, Write},
format_args as fa, mem, format_args as fa, mem,
ops::{self, Range}, ops::{self, Range},
usize,
}, },
hashbrown::hash_map, hashbrown::hash_map,
hbbytecode::DisasmError, hbbytecode::DisasmError,
std::panic,
}; };
pub const VOID: Nid = 0; pub const VOID: Nid = 0;
@ -515,10 +513,6 @@ impl Nodes {
} }
cursor = self.idom(cursor, Some(scheds)); cursor = self.idom(cursor, Some(scheds));
} }
//if out == 110 && load == 108 {
// panic!("{min} {cursor} {}", antideps[cursor as usize] == load)
//}
break; break;
} }
Kind::Phi => { Kind::Phi => {
@ -3293,9 +3287,7 @@ impl<'a> Codegen<'a> {
} }
Expr::BinOp { left, pos, op: TokenKind::Assign, right } => { Expr::BinOp { left, pos, op: TokenKind::Assign, right } => {
let dest = self.raw_expr(left)?; let dest = self.raw_expr(left)?;
let mut value = self.expr_ctx(right, Ctx::default().with_ty(dest.ty))?; let value = self.checked_expr(right, dest.ty, "assignment source")?;
self.assert_ty(pos, &mut value, dest.ty, "assignment source");
if dest.var { if dest.var {
let var = &mut self.ci.scope.vars[(u16::MAX - dest.id) as usize]; let var = &mut self.ci.scope.vars[(u16::MAX - dest.id) as usize];
@ -3425,13 +3417,12 @@ impl<'a> Codegen<'a> {
bs.ty = base; bs.ty = base;
} }
let mut idx = self.expr_ctx(index, Ctx::default().with_ty(ty::Id::DINT))?; let idx = self.checked_expr(index, ty::Id::DINT, "subscript")?;
match bs.ty.expand() { match bs.ty.expand() {
ty::Kind::Slice(s) => { ty::Kind::Slice(s) => {
let elem = self.tys.ins.slices[s].elem; let elem = self.tys.ins.slices[s].elem;
let size = self.ci.nodes.new_const(ty::Id::INT, self.tys.size_of(elem)); let size = self.ci.nodes.new_const(ty::Id::INT, self.tys.size_of(elem));
self.assert_ty(index.pos(), &mut idx, ty::Id::DINT, "subscript");
let inps = [VOID, idx.id, size]; let inps = [VOID, idx.id, size];
let offset = self.ci.nodes.new_node( let offset = self.ci.nodes.new_node(
ty::Id::INT, ty::Id::INT,
@ -3747,10 +3738,8 @@ impl<'a> Codegen<'a> {
break; break;
}; };
let mut value = self.expr_ctx(field, Ctx::default().with_ty(ty))?; let value = self.checked_expr(field, ty, "tuple field")?;
_ = self.assert_ty(field.pos(), &mut value, ty, "tuple field");
let mem = self.offset(mem, offset); let mem = self.offset(mem, offset);
self.store_mem(mem, ty, value.id); self.store_mem(mem, ty, value.id);
} }
@ -3794,8 +3783,7 @@ impl<'a> Codegen<'a> {
for (field, offset) in for (field, offset) in
fields.iter().zip((0u32..).step_by(elem_size as usize)) fields.iter().zip((0u32..).step_by(elem_size as usize))
{ {
let mut value = self.expr_ctx(field, Ctx::default().with_ty(elem))?; let value = self.checked_expr(field, elem, "array value")?;
_ = self.assert_ty(field.pos(), &mut value, elem, "array value");
let mem = self.offset(mem, offset); let mem = self.offset(mem, offset);
self.store_mem(mem, elem, value.id); self.store_mem(mem, elem, value.id);
} }
@ -3843,8 +3831,7 @@ impl<'a> Codegen<'a> {
let (ty, offset) = (field.ty, 0); let (ty, offset) = (field.ty, 0);
let mut value = self.expr_ctx(&value, Ctx::default().with_ty(ty))?; let value = self.checked_expr(&value, ty, fa!("field {}", name))?;
self.assert_ty(fpos, &mut value, ty, fa!("field {}", name));
let mem = self.offset(mem, offset); let mem = self.offset(mem, offset);
self.store_mem(mem, ty, value.id); self.store_mem(mem, ty, value.id);
@ -3877,9 +3864,8 @@ impl<'a> Codegen<'a> {
continue; continue;
} }
let mut value = let value =
self.expr_ctx(&field.value, Ctx::default().with_ty(ty))?; self.checked_expr(&field.value, ty, fa!("field {}", field.name))?;
self.assert_ty(field.pos, &mut value, ty, fa!("field {}", field.name));
let mem = self.offset(mem, offset); let mem = self.offset(mem, offset);
self.store_mem(mem, ty, value.id); self.store_mem(mem, ty, value.id);
} }
@ -3919,7 +3905,7 @@ impl<'a> Codegen<'a> {
let mut ret = Some(Value::VOID); let mut ret = Some(Value::VOID);
for stmt in stmts { for stmt in stmts {
ret = ret.and(self.expr_ctx(stmt, Ctx::default().with_ty(ty::Id::VOID))); ret = ret.and(self.expr_ctx(stmt, Ctx::default().with_ty(ty::Id::VOID)));
if let Some(mut id) = ret { if let Some(id) = ret {
if id.ty != ty::Id::VOID { if id.ty != ty::Id::VOID {
self.warn( self.warn(
stmt.pos(), stmt.pos(),
@ -3931,7 +3917,6 @@ impl<'a> Codegen<'a> {
), ),
); );
} }
self.assert_ty(stmt.pos(), &mut id, ty::Id::VOID, "statement");
} else { } else {
break; break;
} }
@ -4235,8 +4220,7 @@ impl<'a> Codegen<'a> {
Expr::Break { pos } => self.jump_to(pos, 1), Expr::Break { pos } => self.jump_to(pos, 1),
Expr::Continue { pos } => self.jump_to(pos, 0), Expr::Continue { pos } => self.jump_to(pos, 0),
Expr::If { cond, then, else_, .. } => { Expr::If { cond, then, else_, .. } => {
let mut cnd = self.expr_ctx(cond, Ctx::default().with_ty(ty::Id::BOOL))?; let cnd = self.checked_expr(cond, ty::Id::BOOL, "condition")?;
self.assert_ty(cond.pos(), &mut cnd, ty::Id::BOOL, "condition");
let if_node = self.ci.nodes.new_node( let if_node = self.ci.nodes.new_node(
ty::Id::VOID, ty::Id::VOID,
@ -4391,6 +4375,19 @@ impl<'a> Codegen<'a> {
} }
} }
fn checked_expr(
&mut self,
expr: &Expr,
expected_ty: ty::Id,
hint: impl Display,
) -> Option<Value> {
let mut value = self.raw_expr_ctx(expr, Ctx::default().with_ty(expected_ty))?;
self.strip_var(&mut value);
self.assert_ty(expr.pos(), &mut value, expected_ty, hint);
self.strip_ptr(&mut value);
Some(value)
}
fn gen_field( fn gen_field(
&mut self, &mut self,
ctx: Ctx, ctx: Ctx,