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:
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;