commit 892a2a71ee13a66722ff02480790a482f02d814c
parent 10b2a3268a46af5020e3a1a50bcbd8e7a728eabf
Author: Sebastian <sebastian@sebsite.pw>
Date: Mon, 16 Jan 2023 04:42:08 -0500
check: disallow taking address of void
Fixes an assertion failure when attempting to take the address of void
or an alias of void. Also adds a test for taking the address of null.
Fixes: https://todo.sr.ht/~sircmpwn/hare/665
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/src/check.c b/src/check.c
@@ -3090,7 +3090,13 @@ check_expr_unarithm(struct context *ctx,
}
expr->result = operand->result;
break;
- case UN_ADDRESS:
+ case UN_ADDRESS:;
+ const struct type *result = type_dealias(operand->result);
+ if (result->storage == STORAGE_VOID) {
+ error(ctx, aexpr->loc, expr,
+ "Can't take address of void");
+ return;
+ }
expr->result = type_store_lookup_pointer(
ctx->store, aexpr->loc, operand->result, 0);
break;
diff --git a/tests/29-unarithm.ha b/tests/29-unarithm.ha
@@ -1,3 +1,5 @@
+use rt::{compile, exited, EXIT_SUCCESS};
+
type abool = bool;
fn lnot() void = {
@@ -17,6 +19,21 @@ fn addr() void = {
assert(a == 0 - 2);
let b = 1-1;
assert(b == 0);
+
+ assert(compile("
+ export fn main() void = { &null; };
+ ") as exited != EXIT_SUCCESS);
+ assert(compile("
+ export fn main() void = { &void; };
+ ") as exited != EXIT_SUCCESS);
+ assert(compile("
+ type foo = void;
+ export fn main() void = { &foo; };
+ ") as exited != EXIT_SUCCESS);
+ assert(compile("
+ fn f() void = void;
+ export fn main() void = { &f(); };
+ ") as exited != EXIT_SUCCESS);
};
export fn main() void = {