authorgravatar for justus@klausecker.deJustus Klausecker <justus@klausecker.de> 2025-07-13 16:53:39+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-14 09:59:13-07:00
log29ac68b2537b9a9c67f92cc2a5dd4c35bf1c2b31
treea05c443ab692add1dabd0f504d28c5ca21e9ef01
parentf43f89a70588c2add2a7c84d12eef2852d215f51

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.

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

src/Sema.zig+3-1
......@@ -13041,8 +13041,10 @@ fn analyzeSwitchRuntimeBlock(
1304113041 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(cases_extra.items));
1304213042 sema.air_extra.appendSliceAssumeCapacity(@ptrCast(else_body));
1304313043
13044 const has_any_continues = spa.operand == .loop and child_block.label.?.merges.extra_insts.items.len > 0;
13045
1304413046 return try child_block.addInst(.{
13045 .tag = if (spa.operand == .loop) .loop_switch_br else .switch_br,
13047 .tag = if (has_any_continues) .loop_switch_br else .switch_br,
1304613048 .data = .{ .pl_op = .{
1304713049 .operand = operand,
1304813050 .payload = payload_index,
test/cases/discard_labeled_switch_tag.zig created+12
......@@ -0,0 +1,12 @@
1// https://github.com/ziglang/zig/issues/24323
2
3export fn f() void {
4 const x: u32 = 0;
5 sw: switch (x) {
6 else => if (false) continue :sw undefined,
7 }
8}
9
10// compile
11// backend=stage2,llvm
12// target=native