commit 43b34048dd83bde5d4d2a7d93d37a593a9c12fda
parent f631856549f9d269ccb9b774bb6718292ff83109
Author: Sebastian <sebastian@sebsite.pw>
Date: Wed, 18 May 2022 23:46:06 -0400
check: only lower rconst if value fits into type
For example, '界' can no longer be cast to a u8, but 'a' still can.
Signed-off-by: Sebastian <sebastian@sebsite.pw>
Diffstat:
1 file changed, 31 insertions(+), 0 deletions(-)
diff --git a/src/check.c b/src/check.c
@@ -1294,6 +1294,37 @@ check_expr_cast(struct context *ctx,
gen_typename(secondary));
return;
}
+ if (primary->storage == STORAGE_RCONST) {
+ uint32_t max = 0;
+ switch (secondary->storage) {
+ case STORAGE_RUNE:
+ case STORAGE_U64:
+ case STORAGE_I64:
+ case STORAGE_U32:
+ break;
+ case STORAGE_U16:
+ max = UINT16_MAX;
+ break;
+ case STORAGE_I16:
+ max = INT16_MAX;
+ break;
+ case STORAGE_U8:
+ max = UINT8_MAX;
+ break;
+ case STORAGE_I8:
+ max = INT8_MAX;
+ break;
+ default:
+ assert(0); // Invariant
+ }
+
+ if (max != 0 && value->constant.rune > max) {
+ error(ctx, aexpr->cast.type->loc, expr,
+ "Rune does not fit in %s",
+ gen_typename(secondary));
+ return;
+ }
+ }
break;
}
expr->result = aexpr->cast.kind == C_TEST? &builtin_type_bool : secondary;