From 592204e6ee0961de116cffbf02a4cfd85b55443b Mon Sep 17 00:00:00 2001 From: tyfkda Date: Tue, 23 Apr 2024 09:01:33 +0900 Subject: [PATCH] Prevent assigning to cast expression `_Bool` --- src/cc/backend/codegen_expr.c | 3 +++ src/cc/frontend/parser_expr.c | 6 +++++- src/wcc/gen_wasm.c | 11 +++++++++-- tests/test.sh | 1 + 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/cc/backend/codegen_expr.c b/src/cc/backend/codegen_expr.c index b687f8a20..3cbe85169 100644 --- a/src/cc/backend/codegen_expr.c +++ b/src/cc/backend/codegen_expr.c @@ -165,6 +165,9 @@ void gen_cond_jmp(Expr *cond, bool tf, BB *bb) { static VReg *gen_cast(Expr *expr) { Expr *src = expr->unary.sub; Type *dst_type = expr->type; + if (is_bool(dst_type)) + return gen_expr(make_cond(src)); + int dst_size = type_size(dst_type); #if XCC_TARGET_ARCH == XCC_ARCH_X64 && !defined(__NO_FLONUM) // On x64, cannot cast from double to uint64_t directly. diff --git a/src/cc/frontend/parser_expr.c b/src/cc/frontend/parser_expr.c index 1220f735c..f64f8830b 100644 --- a/src/cc/frontend/parser_expr.c +++ b/src/cc/frontend/parser_expr.c @@ -1007,7 +1007,11 @@ static Expr *parse_cast_expr(void) { Expr *sub = parse_cast_expr(); sub = str_to_char_array_var(curscope, sub); check_cast(type, sub->type, is_zero(sub), true, token); - if (type->kind != TY_VOID && (is_const(sub) || is_bool(type))) + + // Do not reduce cast expression using `make_cast` + // because it ignores `(int)x = 1`. + + if (type->kind != TY_VOID && is_const(sub)) return make_cast(type, token, sub, true); return sub->type->kind != TY_VOID ? new_expr_cast(type, token, sub) : sub; } diff --git a/src/wcc/gen_wasm.c b/src/wcc/gen_wasm.c index 85b74705d..94eefa254 100644 --- a/src/wcc/gen_wasm.c +++ b/src/wcc/gen_wasm.c @@ -863,9 +863,16 @@ static void gen_comma(Expr *expr, bool needval) { } static void gen_cast(Expr *expr, bool needval) { - gen_expr(expr->unary.sub, needval); + Expr *src = expr->unary.sub; + Type *dst_type = expr->type; + if (is_bool(dst_type)) { + gen_expr(make_cond(src), needval); + return; + } + + gen_expr(src, needval); if (needval) - gen_cast_to(expr->type, expr->unary.sub->type); + gen_cast_to(dst_type, src->type); } static void gen_ref(Expr *expr, bool needval) { diff --git a/tests/test.sh b/tests/test.sh index 8ad9fc77a..87f515ecd 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -265,6 +265,7 @@ test_error() { compile_error 'dup enum elem' 'enum Foo { BAR, BAR }; void main(){}' compile_error '+x =' 'void main(){ int x; +x = 45; }' compile_error '(int)x = ' 'void main(){ int x; (int)x = 32; }' + compile_error '(_Bool)x = ' 'void main(){ _Bool x; (_Bool)x = 32; }' compile_error 'compound literal =' 'struct Foo {int x;}; void main(){ struct Foo foo = {1}; (struct Foo){66} = foo; }' compile_error 'compound literal w/o brace' 'void main(){ ++(int)55; }' compile_error 'param and first scope' 'void main(int x){ int x; }'