From d2f046780da9c41b3ca41a7e5e06ee4994a2340a Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 23 Feb 2026 23:28:32 +0100 Subject: [PATCH] - Compiler crash using `??` with a `void?` macro #2973 --- releasenotes.md | 1 + src/compiler/llvm_codegen_expr.c | 2 +- test/test_suite/errors/else_check_void.c3t | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/test_suite/errors/else_check_void.c3t diff --git a/releasenotes.md b/releasenotes.md index b60a0532f..d19d91ca2 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -58,6 +58,7 @@ - Member access on a struct returned by the assignment expression, cause crash #2947 - Trying to slice an indexable type leads to misleading error message #2958 - Warn on use of visibility modifiers on methods. #2962 +- Compiler crash using `??` with a `void?` macro #2973 ## 0.7.9 Change list diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index ed9cf0629..e3ff8326e 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -3921,7 +3921,7 @@ static void llvm_emit_else(GenContext *c, BEValue *be_value, Expr *expr) assert(success_end_block && else_block_exit); // We might have a void here - if (!real_value.value) + if (!real_value.value || LLVMIsUndef(real_value.value)) { assert(type_flatten(expr->type) == type_void); assert(!else_value.value); diff --git a/test/test_suite/errors/else_check_void.c3t b/test/test_suite/errors/else_check_void.c3t new file mode 100644 index 000000000..98a33a17d --- /dev/null +++ b/test/test_suite/errors/else_check_void.c3t @@ -0,0 +1,17 @@ +module test; + +faultdef MALFORMED_RESPONSE; +macro void? set_field(String[] tokens) +{ + if (tokens.len < 2) return MALFORMED_RESPONSE~; +} + +fn void main() +{ + String[] tokens = { "a", "b" }; + set_field(tokens) ?? (void)1; +} + +/* #expect: test.ll + +fefe