commit aa264f4772e86d3ff49e89a3887fe24e8c399b8d
parent ca6ac4e270a1902b6b0275e112bc0f549c0f9f66
Author: Sebastian <sebastian@sebsite.pw>
Date: Thu, 5 Jan 2023 18:05:10 -0500
check: more strict rules for type asserting nullable pointers
The compiler used to not check what the target type of the type
assertion of a nullable pointer was. Because of this, given x is a
nullable *int, expressions like `x as *size` and `x as nullable *int`
were incorrectly allowed. Furthermore, expressions like `x as int` and
`x as size` resulted in an abort() in gen.c.
This has been corrected in accordance with the spec, so now nullable
pointers may be type asserted to null or to a non-nullable pointer type
with the same referent type (i.e. x can now only be type asserted to
null and *int).
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/check.c b/src/check.c
@@ -1447,6 +1447,15 @@ check_expr_cast(struct context *ctx,
"a nullable pointer");
return;
}
+ if (secondary->storage != STORAGE_NULL
+ && (secondary->storage != STORAGE_POINTER
+ || primary->pointer.referent
+ != secondary->pointer.referent
+ || (secondary->pointer.flags & PTR_NULLABLE))) {
+ error(ctx, aexpr->cast.type->loc, expr,
+ "Can only type assert nullable pointer into non-nullable pointer of the same type or null");
+ return;
+ }
break;
}
if (primary->storage != STORAGE_TAGGED) {
diff --git a/tests/03-pointers.ha b/tests/03-pointers.ha
@@ -44,7 +44,7 @@ fn casts() void = {
assert((a as null): nullable *void == null);
let a: nullable *int = &4;
- a as nullable *int;
+ assert(a is *int);
};
fn reject() void = {
@@ -101,6 +101,18 @@ fn reject() void = {
let a = null;
};
") as exited != EXIT_SUCCESS);
+ assert(compile("
+ fn test() void = {
+ let a: nullable *int = &4;
+ a as int;
+ };
+ ") as exited != EXIT_SUCCESS);
+ assert(compile("
+ fn test() void = {
+ let a: nullable *int = &4;
+ a as *str;
+ };
+ ") as exited != EXIT_SUCCESS);
// type assertions on non-nullable pointers are prohibited
assert(compile("