diff --git a/stage0/parser.c b/stage0/parser.c index 0ebdf05686..2c47bec424 100644 --- a/stage0/parser.c +++ b/stage0/parser.c @@ -2953,16 +2953,20 @@ static AstNodeIndex parseSwitchProng(Parser* p) { const AstTokenIndex arrow = expectToken(p, TOKEN_EQUAL_ANGLE_BRACKET_RIGHT); parsePtrPayload(p); - const AstNodeIndex case_body = parseAssignExpr(p); - if (case_body == 0) { - fail(p, "expected expression"); - } const uint32_t items_len = p->scratch.len - items_old_len; AstNodeIndex case_node; switch (items_len) { case 0: - case 1: + case 1: { + // In Zig, .data fields are evaluated in order, so for + // switch_case_one, the items are in data[0] and the body + // (expectSingleAssignExpr) is in data[1]. Since items don't go + // through extra_data here, ordering doesn't matter. + const AstNodeIndex case_body = parseAssignExpr(p); + if (case_body == 0) { + fail(p, "expected expression"); + } case_node = addNode(&p->nodes, (AstNodeItem) { .tag = is_inline @@ -2975,10 +2979,21 @@ static AstNodeIndex parseSwitchProng(Parser* p) { .rhs = case_body, }, }); - break; + } break; default: { + // In Zig, struct literal field init order is guaranteed: + // data[0] = addExtra(listToSpan(items)) -- writes items to + // extra_data first data[1] = expectSingleAssignExpr() -- parses + // body after + // We must maintain this order in C. const AstSubRange span = listToSpan(p, &p->scratch.arr[items_old_len], items_len); + const AstNodeIndex extra_idx + = addExtra(p, (AstNodeIndex[]) { span.start, span.end }, 2); + const AstNodeIndex case_body = parseAssignExpr(p); + if (case_body == 0) { + fail(p, "expected expression"); + } case_node = addNode(&p->nodes, (AstNodeItem) { .tag = is_inline @@ -2986,8 +3001,7 @@ static AstNodeIndex parseSwitchProng(Parser* p) { : AST_NODE_SWITCH_CASE, .main_token = arrow, .data = { - .lhs = addExtra(p, - (AstNodeIndex[]) { span.start, span.end }, 2), + .lhs = extra_idx, .rhs = case_body, }, }); diff --git a/stage0/stages_test.zig b/stage0/stages_test.zig index f627ccd8fd..d3465fb4ff 100644 --- a/stage0/stages_test.zig +++ b/stage0/stages_test.zig @@ -30,50 +30,50 @@ const corpus_files = .{ "../lib/c/inttypes.zig", "../lib/compiler/aro/aro/annex_g.zig", "../lib/compiler/aro/aro/Attribute/names.zig", - //"../lib/compiler/aro/aro/Attribute.zig", + "../lib/compiler/aro/aro/Attribute.zig", "../lib/compiler/aro/aro/Builtins/Builtin.zig", - //"../lib/compiler/aro/aro/Builtins/eval.zig", + "../lib/compiler/aro/aro/Builtins/eval.zig", "../lib/compiler/aro/aro/Builtins/Properties.zig", - //"../lib/compiler/aro/aro/Builtins/TypeDescription.zig", + "../lib/compiler/aro/aro/Builtins/TypeDescription.zig", "../lib/compiler/aro/aro/Builtins.zig", "../lib/compiler/aro/aro/char_info/identifier_tables.zig", //"../lib/compiler/aro/aro/char_info.zig", - //"../lib/compiler/aro/aro/CodeGen.zig", - //"../lib/compiler/aro/aro/Compilation.zig", - //"../lib/compiler/aro/aro/Diagnostics/messages.zig", - //"../lib/compiler/aro/aro/Diagnostics.zig", - //"../lib/compiler/aro/aro/Driver/Distro.zig", - //"../lib/compiler/aro/aro/Driver/Filesystem.zig", - //"../lib/compiler/aro/aro/Driver/GCCDetector.zig", - //"../lib/compiler/aro/aro/Driver/GCCVersion.zig", - //"../lib/compiler/aro/aro/Driver/Multilib.zig", - //"../lib/compiler/aro/aro/Driver.zig", - //"../lib/compiler/aro/aro/features.zig", - //"../lib/compiler/aro/aro/Hideset.zig", - //"../lib/compiler/aro/aro/InitList.zig", - //"../lib/compiler/aro/aro/LangOpts.zig", - //"../lib/compiler/aro/aro/Parser.zig", - //"../lib/compiler/aro/aro/pragmas/gcc.zig", - //"../lib/compiler/aro/aro/pragmas/message.zig", - //"../lib/compiler/aro/aro/pragmas/once.zig", - //"../lib/compiler/aro/aro/pragmas/pack.zig", - //"../lib/compiler/aro/aro/Pragma.zig", - //"../lib/compiler/aro/aro/Preprocessor.zig", - //"../lib/compiler/aro/aro/record_layout.zig", - //"../lib/compiler/aro/aro/Source.zig", - //"../lib/compiler/aro/aro/StringInterner.zig", - //"../lib/compiler/aro/aro/SymbolStack.zig", - //"../lib/compiler/aro/aro/target.zig", - //"../lib/compiler/aro/aro/text_literal.zig", - //"../lib/compiler/aro/aro/Tokenizer.zig", - //"../lib/compiler/aro/aro/toolchains/Linux.zig", - //"../lib/compiler/aro/aro/Toolchain.zig", - //"../lib/compiler/aro/aro/tracy.zig", - //"../lib/compiler/aro/aro/Tree/number_affixes.zig", - //"../lib/compiler/aro/aro/Tree.zig", - //"../lib/compiler/aro/aro/Type.zig", - //"../lib/compiler/aro/aro/Value.zig", - //"../lib/compiler/aro/aro.zig", + "../lib/compiler/aro/aro/CodeGen.zig", + "../lib/compiler/aro/aro/Compilation.zig", + "../lib/compiler/aro/aro/Diagnostics/messages.zig", + "../lib/compiler/aro/aro/Diagnostics.zig", + "../lib/compiler/aro/aro/Driver/Distro.zig", + "../lib/compiler/aro/aro/Driver/Filesystem.zig", + "../lib/compiler/aro/aro/Driver/GCCDetector.zig", + "../lib/compiler/aro/aro/Driver/GCCVersion.zig", + "../lib/compiler/aro/aro/Driver/Multilib.zig", + "../lib/compiler/aro/aro/Driver.zig", + "../lib/compiler/aro/aro/features.zig", + "../lib/compiler/aro/aro/Hideset.zig", + "../lib/compiler/aro/aro/InitList.zig", + "../lib/compiler/aro/aro/LangOpts.zig", + "../lib/compiler/aro/aro/Parser.zig", + "../lib/compiler/aro/aro/pragmas/gcc.zig", + "../lib/compiler/aro/aro/pragmas/message.zig", + "../lib/compiler/aro/aro/pragmas/once.zig", + "../lib/compiler/aro/aro/pragmas/pack.zig", + "../lib/compiler/aro/aro/Pragma.zig", + "../lib/compiler/aro/aro/Preprocessor.zig", + "../lib/compiler/aro/aro/record_layout.zig", + "../lib/compiler/aro/aro/Source.zig", + "../lib/compiler/aro/aro/StringInterner.zig", + "../lib/compiler/aro/aro/SymbolStack.zig", + "../lib/compiler/aro/aro/target.zig", + "../lib/compiler/aro/aro/text_literal.zig", + "../lib/compiler/aro/aro/Tokenizer.zig", + "../lib/compiler/aro/aro/toolchains/Linux.zig", + "../lib/compiler/aro/aro/Toolchain.zig", + "../lib/compiler/aro/aro/tracy.zig", + "../lib/compiler/aro/aro/Tree/number_affixes.zig", + "../lib/compiler/aro/aro/Tree.zig", + "../lib/compiler/aro/aro/Type.zig", + "../lib/compiler/aro/aro/Value.zig", + "../lib/compiler/aro/aro.zig", //"../lib/compiler/aro/backend/Interner.zig", //"../lib/compiler/aro/backend/Ir/x86/Renderer.zig", //"../lib/compiler/aro/backend/Ir.zig",