zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 010a7109caab5d910b7af3528ba3321c3cf6d873 (tree)
parent 7d92160d73d3ae7869f19d99fd35d0a5644421c3
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date:   Mon, 16 Feb 2026 14:01:25 +0000

fix labeled switch: parser passes is_labeled flag, init GenZir continue_block/label_token to UINT32_MAX

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
Mstage0/astgen.c | 38++++++++++++++++++++++++++++++++++++++
Mstage0/astgen_test.zig | 14+++++++++++++-
Mstage0/parser.c | 2+-
3 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/stage0/astgen.c b/stage0/astgen.c @@ -14311,6 +14311,8 @@ static void testDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, decl_block.is_comptime = true; decl_block.instructions_top = ag->scratch_inst_len; decl_block.break_block = UINT32_MAX; + decl_block.continue_block = UINT32_MAX; + decl_block.label_token = UINT32_MAX; decl_block.any_defer_node = UINT32_MAX; // Set up fn_block GenZir (AstGen.zig:4837-4845). @@ -14324,6 +14326,8 @@ static void testDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, fn_block.is_comptime = false; fn_block.instructions_top = ag->scratch_inst_len; fn_block.break_block = UINT32_MAX; + fn_block.continue_block = UINT32_MAX; + fn_block.label_token = UINT32_MAX; fn_block.any_defer_node = UINT32_MAX; // Set within_fn, fn_block and fn_ret_ty for the body @@ -14582,6 +14586,8 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, type_gz.decl_line = decl_line; type_gz.is_comptime = true; type_gz.instructions_top = ag->scratch_inst_len; + type_gz.continue_block = UINT32_MAX; + type_gz.label_token = UINT32_MAX; type_gz.any_defer_node = UINT32_MAX; // For extern fn: emit fn type via fnProtoExprInner into type_gz // (AstGen.zig:4160-4164). @@ -14609,6 +14615,8 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, align_gz.decl_line = decl_line; align_gz.is_comptime = true; align_gz.instructions_top = type_top; + align_gz.continue_block = UINT32_MAX; + align_gz.label_token = UINT32_MAX; align_gz.any_defer_node = UINT32_MAX; if (align_expr_node != 0) { @@ -14633,6 +14641,8 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, linksection_gz.decl_line = decl_line; linksection_gz.is_comptime = true; linksection_gz.instructions_top = align_top; + linksection_gz.continue_block = UINT32_MAX; + linksection_gz.label_token = UINT32_MAX; linksection_gz.any_defer_node = UINT32_MAX; if (section_expr_node != 0) { @@ -14657,6 +14667,8 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, addrspace_gz.decl_line = decl_line; addrspace_gz.is_comptime = true; addrspace_gz.instructions_top = linksection_top; + addrspace_gz.continue_block = UINT32_MAX; + addrspace_gz.label_token = UINT32_MAX; addrspace_gz.any_defer_node = UINT32_MAX; if (addrspace_expr_node != 0) { @@ -14684,6 +14696,8 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, decl_gz.is_comptime = true; decl_gz.instructions_top = addrspace_top; decl_gz.break_block = UINT32_MAX; + decl_gz.continue_block = UINT32_MAX; + decl_gz.label_token = UINT32_MAX; decl_gz.any_defer_node = UINT32_MAX; // For non-extern: process params, return type, calling convention, body @@ -14996,6 +15010,8 @@ static void fnDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, body_gz.decl_line = decl_line; body_gz.is_comptime = false; body_gz.instructions_top = ag->scratch_inst_len; + body_gz.continue_block = UINT32_MAX; + body_gz.label_token = UINT32_MAX; body_gz.any_defer_node = UINT32_MAX; // Set fn_block, fn_ret_ty, fn_var_args for the body @@ -15209,6 +15225,8 @@ static void comptimeDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, value_gz.decl_line = decl_line; value_gz.is_comptime = true; value_gz.instructions_top = ag->scratch_inst_len; + value_gz.continue_block = UINT32_MAX; + value_gz.label_token = UINT32_MAX; value_gz.any_defer_node = UINT32_MAX; // Evaluate the body expression (AstGen.zig:4684). @@ -15536,6 +15554,8 @@ static void globalVarDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, type_gz.instructions_top = ag->scratch_inst_len; type_gz.decl_line = ag->source_line; type_gz.is_comptime = true; + type_gz.continue_block = UINT32_MAX; + type_gz.label_token = UINT32_MAX; type_gz.any_defer_node = UINT32_MAX; if (vd.type_node != 0) { @@ -15556,6 +15576,8 @@ static void globalVarDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, align_gz.instructions_top = type_top; align_gz.decl_line = ag->source_line; align_gz.is_comptime = true; + align_gz.continue_block = UINT32_MAX; + align_gz.label_token = UINT32_MAX; align_gz.any_defer_node = UINT32_MAX; if (vd.align_node != 0) { @@ -15582,6 +15604,8 @@ static void globalVarDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, linksection_gz.instructions_top = align_top; linksection_gz.decl_line = ag->source_line; linksection_gz.is_comptime = true; + linksection_gz.continue_block = UINT32_MAX; + linksection_gz.label_token = UINT32_MAX; linksection_gz.any_defer_node = UINT32_MAX; if (vd.section_node != 0) { @@ -15608,6 +15632,8 @@ static void globalVarDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, addrspace_gz.instructions_top = linksection_top; addrspace_gz.decl_line = ag->source_line; addrspace_gz.is_comptime = true; + addrspace_gz.continue_block = UINT32_MAX; + addrspace_gz.label_token = UINT32_MAX; addrspace_gz.any_defer_node = UINT32_MAX; if (vd.addrspace_node != 0) { @@ -15636,6 +15662,8 @@ static void globalVarDecl(AstGenCtx* ag, GenZir* gz, Scope* scope, value_gz.instructions_top = addrspace_top; value_gz.decl_line = ag->source_line; value_gz.is_comptime = true; + value_gz.continue_block = UINT32_MAX; + value_gz.label_token = UINT32_MAX; value_gz.any_defer_node = UINT32_MAX; if (vd.init_node != UINT32_MAX && vd.init_node != 0) { @@ -16323,6 +16351,8 @@ static uint32_t enumDeclInner(AstGenCtx* ag, GenZir* gz, Scope* scope, block_scope.decl_line = gz->decl_line; // AstGen.zig:5627: gz.decl_line block_scope.is_comptime = true; block_scope.instructions_top = ag->scratch_inst_len; + block_scope.continue_block = UINT32_MAX; + block_scope.label_token = UINT32_MAX; block_scope.any_defer_node = UINT32_MAX; // Evaluate tag type argument if present (AstGen.zig:5638-5641). @@ -16639,6 +16669,8 @@ static uint32_t unionDeclInner(AstGenCtx* ag, GenZir* gz, Scope* scope, block_scope.decl_line = gz->decl_line; block_scope.is_comptime = true; block_scope.instructions_top = ag->scratch_inst_len; + block_scope.continue_block = UINT32_MAX; + block_scope.label_token = UINT32_MAX; block_scope.any_defer_node = UINT32_MAX; // Scan container (AstGen.zig:5328). @@ -16944,6 +16976,8 @@ static uint32_t structDeclInner(AstGenCtx* ag, GenZir* gz, Scope* scope, block_scope.decl_line = gz->decl_line; // Fix #7: use gz->decl_line block_scope.is_comptime = true; block_scope.instructions_top = ag->scratch_inst_len; + block_scope.continue_block = UINT32_MAX; + block_scope.label_token = UINT32_MAX; block_scope.any_defer_node = UINT32_MAX; // Handle backing_int_node for packed structs (AstGen.zig:5000-5024). @@ -17281,6 +17315,8 @@ static uint32_t opaqueDeclInner(AstGenCtx* ag, GenZir* gz, Scope* scope, block_scope.decl_line = gz->decl_line; block_scope.is_comptime = true; block_scope.instructions_top = ag->scratch_inst_len; + block_scope.continue_block = UINT32_MAX; + block_scope.label_token = UINT32_MAX; block_scope.any_defer_node = UINT32_MAX; // scanContainer for declarations (AstGen.zig:5756). @@ -18628,6 +18664,8 @@ Zir astGen(const Ast* ast) { gen_scope.decl_node_index = 0; // root gen_scope.decl_line = 0; gen_scope.break_block = UINT32_MAX; + gen_scope.continue_block = UINT32_MAX; + gen_scope.label_token = UINT32_MAX; gen_scope.any_defer_node = UINT32_MAX; // Get root container members: containerDeclRoot (AstGen.zig:191-195). diff --git a/stage0/astgen_test.zig b/stage0/astgen_test.zig @@ -1287,7 +1287,7 @@ const corpus_files = .{ "../test/behavior/string_literals.zig", "../test/behavior/struct_contains_null_ptr_itself.zig", "../test/behavior/struct_contains_slice_of_itself.zig", - //"../test/behavior/switch_loop.zig", + "../test/behavior/switch_loop.zig", "../test/behavior/switch_prong_err_enum.zig", "../test/behavior/switch_prong_implicit_cast.zig", "../test/behavior/this.zig", @@ -1309,6 +1309,18 @@ const corpus_files = .{ "../test/behavior/wrapping_arithmetic.zig", "../test/behavior/x86_64.zig", //"../test/behavior/zon.zig", + //"../src/print_value.zig", + //"../src/crash_report.zig", + //"../src/target.zig", + //"../src/link.zig", + //"../src/Air.zig", + //"../src/print_zir.zig", + //"../src/Value.zig", + //"../src/Type.zig", + //"../src/translate_c.zig", + //"../src/Compilation.zig", + //"../src/InternPool.zig", + //"../src/Sema.zig", }; fn corpusCheck(gpa: Allocator, source: [:0]const u8) !void { diff --git a/stage0/parser.c b/stage0/parser.c @@ -978,7 +978,7 @@ static AstNodeIndex parseLabeledStatement(Parser* p) { if (loop_stmt != 0) return loop_stmt; - const AstNodeIndex switch_expr = parseSwitchExpr(p, false); + const AstNodeIndex switch_expr = parseSwitchExpr(p, label_token != 0); if (switch_expr != 0) return switch_expr;