harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

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:
Msrc/check.c | 8+++++++-
Mtests/29-unarithm.ha | 17+++++++++++++++++
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 = {