diff --git a/releasenotes.md b/releasenotes.md index 195e2fef1..b3cfccbcb 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -9,6 +9,7 @@ ### Fixes - List.remove_at would incorrectly trigger ASAN. - With avx512, passing a 512 bit vector in a union would be lowered incorrectly, causing an assert. #2362 +- Codegen error in `if (try x = (true ? io::EOF? : 1))`, i.e. using if-try with a known Empty. ### Stdlib changes - Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`. diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index 394a4d185..7bffbaecf 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4263,18 +4263,26 @@ void llvm_emit_try_assign_try_catch(GenContext *c, bool is_try, BEValue *be_valu // 6. If we haven't jumped yet, do it here (on error) to the catch block. llvm_value_fold_optional(c, be_value); - // 7. If we have a variable, then we make the store. - if (var_addr) + // 7. Store the success block. + LLVMBasicBlockRef success_block = llvm_get_current_block_if_in_use(c); + + // 8. If we have a variable, then we make the store. + if (success_block && var_addr) { ASSERT(is_try && "Storing will only happen on try."); llvm_store(c, var_addr, be_value); } - // 8. Restore the error stack. + // 9. Restore the error stack. POP_CATCH(); - // 9. Store the success block. - LLVMBasicBlockRef success_block = c->current_block; + // 10. Special handling if no success. + if (!success_block) + { + llvm_emit_block(c, catch_block); + llvm_value_set(be_value, LLVMConstInt(c->bool_type, is_try ? 0 : 1, false), type_bool); + return; + } // 10. Jump to the phi llvm_emit_br(c, phi_catch); diff --git a/test/test_suite/errors/try_known_optional.c3t b/test/test_suite/errors/try_known_optional.c3t new file mode 100644 index 000000000..b2557a097 --- /dev/null +++ b/test/test_suite/errors/try_known_optional.c3t @@ -0,0 +1,20 @@ +// #target: macos-x64 +module test; +import std; +fn int main() +{ + if (try x = (true ? io::EOF? : 3)) + {} + return 0; +} + +/* #expect: test.ll + +entry: + %x = alloca i32, align 4 + store i32 0, ptr %x, align 4 + br label %catch_landing + +catch_landing: ; preds = %entry + ret i32 0 +}