Commit 6f7939a452

LemonBoy <thatlemon@gmail.com>
2019-10-19 16:20:30
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
1 parent bab93e7
Changed files (2)
src
test
stage1
behavior
src/ir.cpp
@@ -19251,7 +19251,7 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
 
     ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type;
     ConstExprValue *pointee_val = nullptr;
-    if (instr_is_comptime(target_value_ptr)) {
+    if (instr_is_comptime(target_value_ptr) && target_value_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
         pointee_val = const_ptr_pointee(ira, ira->codegen, &target_value_ptr->value, target_value_ptr->source_node);
         if (pointee_val == nullptr)
             return ira->codegen->invalid_instruction;
test/stage1/behavior/switch.zig
@@ -434,3 +434,21 @@ test "switch with disjoint range" {
         126...126 => {},
     }
 }
+
+var state: u32 = 0;
+fn poll() void {
+    switch (state) {
+        0 => {
+            state = 1;
+        },
+        else => {
+            state += 1;
+        },
+    }
+}
+
+test "switch on global mutable var isn't constant-folded" {
+    while (state < 2) {
+        poll();
+    }
+}