From 29ac68b2537b9a9c67f92cc2a5dd4c35bf1c2b31 Mon Sep 17 00:00:00 2001 From: Justus Klausecker Date: Sun, 13 Jul 2025 16:53:39 +0200 Subject: [PATCH] Sema: Fix invalid AIR generation for switch loop with comptime discarded tag Add an additional check before emitting `.loop_switch_br` instead of `.switch_br` in a tagged switch statement for whether any of the continues referencing its tag are actually runtime reachable. This fixes triggering an assertion in Liveness caused by the invalid assumption that every tagged switch must be a loop if its tag is referenced in any way even if this reference is not runtime reachable. --- src/Sema.zig | 4 +++- test/cases/discard_labeled_switch_tag.zig | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test/cases/discard_labeled_switch_tag.zig diff --git a/src/Sema.zig b/src/Sema.zig index 81331f3ccc..6672ba5b36 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -13041,8 +13041,10 @@ fn analyzeSwitchRuntimeBlock( sema.air_extra.appendSliceAssumeCapacity(@ptrCast(cases_extra.items)); sema.air_extra.appendSliceAssumeCapacity(@ptrCast(else_body)); + const has_any_continues = spa.operand == .loop and child_block.label.?.merges.extra_insts.items.len > 0; + return try child_block.addInst(.{ - .tag = if (spa.operand == .loop) .loop_switch_br else .switch_br, + .tag = if (has_any_continues) .loop_switch_br else .switch_br, .data = .{ .pl_op = .{ .operand = operand, .payload = payload_index, diff --git a/test/cases/discard_labeled_switch_tag.zig b/test/cases/discard_labeled_switch_tag.zig new file mode 100644 index 0000000000..63aa304b40 --- /dev/null +++ b/test/cases/discard_labeled_switch_tag.zig @@ -0,0 +1,12 @@ +// https://github.com/ziglang/zig/issues/24323 + +export fn f() void { + const x: u32 = 0; + sw: switch (x) { + else => if (false) continue :sw undefined, + } +} + +// compile +// backend=stage2,llvm +// target=native