diff --git a/src/codegen/x86_64/CodeGen.zig b/src/codegen/x86_64/CodeGen.zig index 97865d02b6f6247d285cee01f1abe03f42d908b7..b2335f3c7dfff9213e7af715123a9151dd0b0721 100644 --- a/src/codegen/x86_64/CodeGen.zig +++ b/src/codegen/x86_64/CodeGen.zig @@ -177120,8 +177120,6 @@ fn lowerSwitchBr( var bfa: std.heap.BufferFirstAllocator = .init(@ptrCast(&bfa_buf), cg.gpa); const allocator = bfa.allocator(); - const state = try cg.saveState(); - const liveness = try cg.liveness.getSwitchBr(allocator, inst, switch_br.cases_len + 1); defer allocator.free(liveness.deaths); @@ -177232,6 +177230,7 @@ fn lowerSwitchBr( } }; var cases_it = switch_br.iterateCases(); + const state = try cg.saveState(); while (cases_it.next()) |case| { { const table = cg.mir_table.items[table_start..][0..table_len]; @@ -177388,6 +177387,7 @@ fn lowerSwitchBr( // The jump to skip this case if the conditions all failed. const skip_case_reloc = try cg.asmJmpReloc(undefined); + const state = try cg.saveState(); for (liveness.deaths[case.idx]) |operand| try cg.processDeath(operand, .{}); @@ -177406,6 +177406,7 @@ fn lowerSwitchBr( } if (switch_br.else_body_len > 0) { const else_body = cases_it.elseBody(); + const state = try cg.saveState(); const else_deaths = liveness.deaths.len - 1; for (liveness.deaths[else_deaths]) |operand| try cg.processDeath(operand, .{}); diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 25eb5159357c06134f6b8e2f3fa5276528b7d4c4..1533d6d5693c7b6e283eab6653d8e018ea0c2d33 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -1568,3 +1568,16 @@ test "union field pointer capture preserves alignment in inline prong" { try comptime U.doTheTest(&.{ .a = 123 }); try comptime U.doTheTest(&.{ .b = 123 }); } + +test "switch on expression" { + var a: []const []const u8 = &.{ "b", "b", "A", "A", "b" }; + _ = &a; + var c: isize = 0; + for (a[1..]) |b| { + switch (b[0] % 2) { + 0 => c += 1, + else => c -= 1, + } + } + try expect(c == 0); +}