Skip to content

Commit

Permalink
AstGen: do not allow unlabeled break to exit a labeled switch
Browse files Browse the repository at this point in the history
`break`ing from something which isn't a loop should always be opt-in.
This was a bug in ziglang#21257.
  • Loading branch information
mlugg authored and DivergentClouds committed Sep 24, 2024
1 parent 0901a33 commit f985b9c
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
4 changes: 2 additions & 2 deletions lib/std/zig/AstGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -7811,9 +7811,7 @@ fn switchExpr(
const switch_block = try parent_gz.makeBlockInst(switch_tag, node);

if (switch_full.label_token) |label_token| {
block_scope.break_block = switch_block.toOptional();
block_scope.continue_block = switch_block.toOptional();
// `break_result_info` already set above
block_scope.continue_result_info = .{
.rl = if (any_payload_is_ref)
.{ .ref_coerced_ty = raw_operand_ty_ref }
Expand All @@ -7825,6 +7823,8 @@ fn switchExpr(
.token = label_token,
.block_inst = switch_block,
};
// `break` can target this via `label.block_inst`
// `break_result_info` already set by `setBreakResultInfo`
}

// We re-use this same scope for all cases, including the special prong, if any.
Expand Down
17 changes: 17 additions & 0 deletions test/behavior/switch.zig
Original file line number Diff line number Diff line change
Expand Up @@ -985,3 +985,20 @@ test "labeled switch with break" {

comptime assert(comptime_val);
}

test "unlabeled break ignores switch" {
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO

const result = while (true) {
_ = s: switch (@as(u32, 1)) {
1 => continue :s 123,
else => |x| break x,
};
comptime unreachable; // control flow never breaks from the switch
};
try expect(result == 123);
}

0 comments on commit f985b9c

Please sign in to comment.