authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-10-19 16:20:30+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-10-19 13:48:26-04:00
log6f7939a452e69b77581f5390b8075e9dfa81b03e
tree4b671d6369b5508ca6ce718fad2df3a1fd23cf6e
parentbab93e75611de79a1a1e898b0c9e45905817189f

Prevent too eager constant-folding of switch expression

A pointer was wrongly assumed to be comptime-available causing the analysis pass to assume its initial value was constant. Fixes #3481

2 files changed, 19 insertions(+), 1 deletions(-)

src/ir.cpp+1-1
...@@ -19251,7 +19251,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -19251,7 +19251,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1925119251
19252 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type;19252 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type;
19253 ConstExprValue *pointee_val = nullptr;19253 ConstExprValue *pointee_val = nullptr;
19254 if (instr_is_comptime(target_value_ptr)) {19254 if (instr_is_comptime(target_value_ptr) && target_value_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
19255 pointee_val = const_ptr_pointee(ira, ira->codegen, &target_value_ptr->value, target_value_ptr->source_node);19255 pointee_val = const_ptr_pointee(ira, ira->codegen, &target_value_ptr->value, target_value_ptr->source_node);
19256 if (pointee_val == nullptr)19256 if (pointee_val == nullptr)
19257 return ira->codegen->invalid_instruction;19257 return ira->codegen->invalid_instruction;
test/stage1/behavior/switch.zig+18
...@@ -434,3 +434,21 @@ test "switch with disjoint range" {...@@ -434,3 +434,21 @@ test "switch with disjoint range" {
434 126...126 => {},434 126...126 => {},
435 }435 }
436}436}
437
438var state: u32 = 0;
439fn poll() void {
440 switch (state) {
441 0 => {
442 state = 1;
443 },
444 else => {
445 state += 1;
446 },
447 }
448}
449
450test "switch on global mutable var isn't constant-folded" {
451 while (state < 2) {
452 poll();
453 }
454}