From 4a5b0cde1330e0410612838a42dad62cc30b0e92 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 2 Sep 2019 20:28:25 -0400 Subject: [PATCH] fix const result loc, runtime if cond, else unreachable Closes #2791. See that issue for more details; I documented the debugging process quite thoroughly on this one. --- src/codegen.cpp | 9 +++++++++ test/stage1/behavior/if.zig | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/codegen.cpp b/src/codegen.cpp index 74de8634cc..0b51df1e82 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -3522,6 +3522,15 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir assert(ptr_type->id == ZigTypeIdPointer); if (!type_has_bits(ptr_type)) return nullptr; + if (instruction->ptr->ref_count == 0) { + // In this case, this StorePtr instruction should be elided. Something happened like this: + // var t = true; + // const x = if (t) Num.Two else unreachable; + // The if condition is a runtime value, so the StorePtr for `x = Num.Two` got generated + // (this instruction being rendered) but because of `else unreachable` the result ended + // up being a comptime const value. + return nullptr; + } bool have_init_expr = !value_is_all_undef(&instruction->value->value); if (have_init_expr) { diff --git a/test/stage1/behavior/if.zig b/test/stage1/behavior/if.zig index 5f92962957..70712ea85a 100644 --- a/test/stage1/behavior/if.zig +++ b/test/stage1/behavior/if.zig @@ -63,3 +63,14 @@ test "labeled break inside comptime if inside runtime if" { } expect(answer == 42); } + +test "const result loc, runtime if cond, else unreachable" { + const Num = enum { + One, + Two, + }; + + var t = true; + const x = if (t) Num.Two else unreachable; + if (x != .Two) @compileError("bad"); +}