From d727696830260ca64f5e8d54f38c94b9bcba33a1 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 21 Sep 2024 00:57:36 +0200 Subject: [PATCH] Segfault using ternary with no assignment #1468. --- releasenotes.md | 1 + src/compiler/llvm_codegen_expr.c | 5 ++++ test/test_suite/expressions/ternary_void.c3t | 31 ++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 test/test_suite/expressions/ternary_void.c3t diff --git a/releasenotes.md b/releasenotes.md index ea2669429..420c218a9 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -46,6 +46,7 @@ - Folding a constant array of structs at compile time would cause an assert. - Enum attributes would be overwritten by enum value attributes. - LLVM issue with try when bool is combined #1467 +- Segfault using ternary with no assignment #1468 ### Stdlib changes - Additional init functions for hashmap. diff --git a/src/compiler/llvm_codegen_expr.c b/src/compiler/llvm_codegen_expr.c index d590fbffa..22dbe9b98 100644 --- a/src/compiler/llvm_codegen_expr.c +++ b/src/compiler/llvm_codegen_expr.c @@ -4969,6 +4969,11 @@ void gencontext_emit_ternary_expr(GenContext *c, BEValue *value, Expr *expr) return; } + if (expr->type == type_void) + { + llvm_value_set(value, NULL, expr->type); + return; + } llvm_new_phi(c, value, "val", expr->type, lhs_value, lhs_exit, rhs_value, rhs_exit); } static LLVMValueRef llvm_emit_real(LLVMTypeRef type, Float f) diff --git a/test/test_suite/expressions/ternary_void.c3t b/test/test_suite/expressions/ternary_void.c3t new file mode 100644 index 000000000..91f1d60f8 --- /dev/null +++ b/test/test_suite/expressions/ternary_void.c3t @@ -0,0 +1,31 @@ +// #target: macos-x64 +module test; + +fn void foo() { } +fn void bar() {} + +fn void main() +{ + bool b = true; + true ? foo() : bar(); // ok + b ? foo() : bar(); // segfault +} + +/* #expect: test.ll + +entry: + %b = alloca i8, align 1 + store i8 1, ptr %b, align 1 + call void @test.foo() + %0 = load i8, ptr %b, align 1 + %1 = trunc i8 %0 to i1 + br i1 %1, label %cond.lhs, label %cond.rhs +cond.lhs: ; preds = %entry + call void @test.foo() + br label %cond.phi +cond.rhs: ; preds = %entry + call void @test.bar() + br label %cond.phi +cond.phi: ; preds = %cond.rhs, %cond.lhs + ret void +}