From 6f7939a452e69b77581f5390b8075e9dfa81b03e Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 19 Oct 2019 16:20:30 +0200 Subject: [PATCH] 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 --- src/ir.cpp | 2 +- test/stage1/behavior/switch.zig | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/ir.cpp b/src/ir.cpp index 981aa55b2a..2ceabb91b0 100644 --- a/src/ir.cpp +++ b/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; diff --git a/test/stage1/behavior/switch.zig b/test/stage1/behavior/switch.zig index bc1b4a7a09..936dbed786 100644 --- a/test/stage1/behavior/switch.zig +++ b/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(); + } +}