authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-02 20:28:25-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-09-02 20:28:25-04:00
log4a5b0cde1330e0410612838a42dad62cc30b0e92
treeac182440d6b067eeaa2159c26c240387ae51397d
parentab4cba14c8aac7151b4c10094fea4211694da145
signaturelock-open Commit is signed but in an unrecognized format.

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.

2 files changed, 20 insertions(+), 0 deletions(-)

src/codegen.cpp+9
......@@ -3522,6 +3522,15 @@ static LLVMValueRef ir_render_store_ptr(CodeGen *g, IrExecutable *executable, Ir
35223522 assert(ptr_type->id == ZigTypeIdPointer);
35233523 if (!type_has_bits(ptr_type))
35243524 return nullptr;
3525 if (instruction->ptr->ref_count == 0) {
3526 // In this case, this StorePtr instruction should be elided. Something happened like this:
3527 // var t = true;
3528 // const x = if (t) Num.Two else unreachable;
3529 // The if condition is a runtime value, so the StorePtr for `x = Num.Two` got generated
3530 // (this instruction being rendered) but because of `else unreachable` the result ended
3531 // up being a comptime const value.
3532 return nullptr;
3533 }
35253534
35263535 bool have_init_expr = !value_is_all_undef(&instruction->value->value);
35273536 if (have_init_expr) {
test/stage1/behavior/if.zig+11
......@@ -63,3 +63,14 @@ test "labeled break inside comptime if inside runtime if" {
6363 }
6464 expect(answer == 42);
6565}
66
67test "const result loc, runtime if cond, else unreachable" {
68 const Num = enum {
69 One,
70 Two,
71 };
72
73 var t = true;
74 const x = if (t) Num.Two else unreachable;
75 if (x != .Two) @compileError("bad");
76}