forked from AbleOS/holey-bytes
properly type checking, null checks are fixed
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
1ca9529302
commit
e65c72e19f
|
@ -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}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue