diff --git a/build.zig b/build.zig index 2a60a81608..b4c2ef34e9 100644 --- a/build.zig +++ b/build.zig @@ -657,7 +657,7 @@ pub fn build(b: *std.Build) !void { // zig0 (C implementation) build steps const zig0_cc = b.option([]const u8, "zig0-cc", "C compiler for zig0 tests") orelse "zig"; const zig0_no_exec = b.option(bool, "zig0-no-exec", "Compile zig0 test binary without running it") orelse false; - const zig0_test_timeout = b.option([]const u8, "zig0-test-timeout", "Test execution timeout for zig0 (default: 10s, none with valgrind)"); + const zig0_test_timeout = b.option([]const u8, "zig0-test-timeout", "Test execution timeout for zig0"); const zig0_valgrind = valgrind orelse false; const zig0_target = blk: { @@ -1615,7 +1615,7 @@ fn addZig0TestStep( addZig0CSources(b, test_mod, cc, optimize); test_mod.linkSystemLibrary("c", .{}); - const timeout: ?[]const u8 = test_timeout orelse if (valgrind) null else "10"; + const timeout: ?[]const u8 = test_timeout orelse if (valgrind) null else "300"; const test_exe = b.addTest(.{ .root_module = test_mod, diff --git a/stage0/astgen.c b/stage0/astgen.c index e9a02ca018..790c06f5d7 100644 --- a/stage0/astgen.c +++ b/stage0/astgen.c @@ -6424,9 +6424,14 @@ static uint32_t ptrTypeExpr(GenZir* gz, Scope* scope, uint32_t node) { ag->source_offset = saved_source_offset; ag->source_line = saved_source_line; ag->source_column = saved_source_column; - // Upstream creates addrspace_ty via addBuiltinValue, we don't have - // that yet, so pass RL_NONE (matching previous behavior). - addrspace_ref = comptimeExpr(gz, scope, RL_NONE_VAL, addrspace_node, + // AstGen.zig:3880-3881 + uint32_t addrspace_ty = addBuiltinValue(gz, addrspace_node, + ZIR_BUILTIN_VALUE_ADDRESS_SPACE); + ResultLoc asrl = { .tag = RL_COERCED_TY, + .data = addrspace_ty, + .src_node = 0, + .ctx = RI_CTX_NONE }; + addrspace_ref = comptimeExpr(gz, scope, asrl, addrspace_node, addrspace_node, COMPTIME_REASON_ADDRSPACE); trailing_count++; } @@ -8048,6 +8053,9 @@ static uint32_t boolBinOp( } // Mirrors nodeIsTriviallyZero (AstGen.zig:10299-10313). +// Uses parseNumberLiteral semantics: returns true when the number literal +// parses to integer value 0 (handles 0, 0b0, 0o0, 0x0, and variants with +// underscores like 0b0000_000). static bool nodeIsTriviallyZero(const Ast* tree, uint32_t node) { if (tree->nodes.tags[node] != AST_NODE_NUMBER_LITERAL) return false; @@ -8056,18 +8064,27 @@ static bool nodeIsTriviallyZero(const Ast* tree, uint32_t node) { const char* source = (const char*)tree->source; if (source[tok_start] != '0') return false; - // Distinguish "0.." (range, token is "0") from "0.5" (float literal). char c = source[tok_start + 1]; + // Distinguish "0.." (range, token is "0") from "0.5" (float literal). if (c == '.') return source[tok_start + 2] == '.'; - // Any alphanumeric or underscore means the token is longer than "0". - if (c >= '0' && c <= '9') - return false; - if (c >= 'a' && c <= 'z') - return false; - if (c >= 'A' && c <= 'Z') - return false; - if (c == '_') + // Handle prefixed forms: 0b, 0o, 0x (case insensitive). + if (c == 'b' || c == 'B' || c == 'o' || c == 'O' || c == 'x' || c == 'X') { + // Check that all remaining digits are '0' or '_'. + for (uint32_t i = tok_start + 2; ; i++) { + char d = source[i]; + if (d == '0' || d == '_') + continue; + // End of token: any character not valid in a number literal. + if ((d >= '0' && d <= '9') || (d >= 'a' && d <= 'z') + || (d >= 'A' && d <= 'Z')) + return false; // non-zero digit + return true; + } + } + // Any other character after '0' means the token is longer than "0" + // (e.g. "00", "0_0", decimal digits). + if ((c >= '0' && c <= '9') || c == '_') return false; return true; } @@ -9719,7 +9736,7 @@ static uint32_t ifExpr(GenZir* gz, Scope* scope, ResultLoc rl, uint32_t node) { GenZir else_scope = makeSubBlock(gz, scope); // save_err_ret_index (AstGen.zig:6448-6449). - bool do_err_trace = ag->fn_ret_ty != 0 && error_token != 0; + bool do_err_trace = ag->fn_block != NULL && error_token != 0; if (do_err_trace && nodeMayAppendToErrorTrace(tree, cond_node)) addSaveErrRetIndex(&else_scope, ZIR_REF_NONE); @@ -10162,7 +10179,7 @@ static uint32_t orelseCatchExpr(GenZir* gz, Scope* scope, ResultLoc rl, const Ast* tree = ag->tree; AstData nd = tree->nodes.datas[node]; - bool do_err_trace = ag->fn_ret_ty != 0 + bool do_err_trace = ag->fn_block != NULL && (cond_op == ZIR_INST_IS_NON_ERR || cond_op == ZIR_INST_IS_NON_ERR_PTR); @@ -10775,7 +10792,7 @@ static uint32_t switchExprErrUnion(GenZir* parent_gz, Scope* scope, const uint32_t* case_nodes_arr = tree->extra_data.arr + cases_start; uint32_t case_count = cases_end - cases_start; - bool do_err_trace = (ag->fn_ret_ty != 0); + bool do_err_trace = (ag->fn_block != NULL); bool need_rl = nodesNeedRlContains(ag, catch_or_if_node); ResultLoc break_rl = breakResultInfo(parent_gz, rl, catch_or_if_node, need_rl); @@ -11478,7 +11495,8 @@ static uint32_t switchExpr( free(pay); return ZIR_REF_VOID_VALUE; } - capture = 0; // none + // capture stays as by_val (matching Zig: capture is not + // reset for underscore discards, AstGen.zig:7870) // sub_scope stays as &case_scope.base } else { // Named capture (AstGen.zig:7880-7892). @@ -13215,16 +13233,25 @@ static void genDefersBoth(GenZir* gz, const Scope* outer_scope, static void blockExprStmts(GenZir* gz, Scope* scope, const uint32_t* statements, uint32_t stmt_count) { AstGenCtx* ag = gz->astgen; - // Stack-allocated scope storage for local variables and defers. - // Max 128 local variable declarations and 128 defers per block. - ScopeLocalVal val_scopes[128]; - ScopeLocalPtr ptr_scopes[128]; - ScopeDefer defer_scopes[128]; + // Heap-allocated scope storage for local variables and defers. + // Each statement can produce at most one scope, so stmt_count is the + // upper bound; use a minimum of 128 for small blocks. + uint32_t max_scopes = stmt_count > 128 ? stmt_count : 128; + ScopeLocalVal* val_scopes = malloc(max_scopes * sizeof(ScopeLocalVal)); + ScopeLocalPtr* ptr_scopes = malloc(max_scopes * sizeof(ScopeLocalPtr)); + ScopeDefer* defer_scopes = malloc(max_scopes * sizeof(ScopeDefer)); uint32_t val_idx = 0; uint32_t ptr_idx = 0; uint32_t defer_idx = 0; Scope* cur_scope = scope; bool noreturn_stmt = false; + if (!val_scopes || !ptr_scopes || !defer_scopes) { + free(val_scopes); + free(ptr_scopes); + free(defer_scopes); + SET_ERROR(ag); + return; + } for (uint32_t i = 0; i < stmt_count; i++) { if (ag->has_compile_errors) @@ -13243,7 +13270,7 @@ static void blockExprStmts(GenZir* gz, Scope* scope, case AST_NODE_ASSIGN_DESTRUCTURE: cur_scope = assignDestructureMaybeDecls(gz, cur_scope, inner_node, - val_scopes, &val_idx, ptr_scopes, &ptr_idx, 128); + val_scopes, &val_idx, ptr_scopes, &ptr_idx, max_scopes); break; // Shift assignment operators (AstGen.zig:2585-2586). case AST_NODE_ASSIGN_SHL: @@ -13302,7 +13329,7 @@ static void blockExprStmts(GenZir* gz, Scope* scope, case AST_NODE_SIMPLE_VAR_DECL: case AST_NODE_LOCAL_VAR_DECL: case AST_NODE_ALIGNED_VAR_DECL: - if (val_idx < 128 && ptr_idx < 128) { + if (val_idx < max_scopes && ptr_idx < max_scopes) { varDecl(gz, cur_scope, stmt, &val_scopes[val_idx], &ptr_scopes[ptr_idx], &cur_scope); // Check which one was used: if scope now points to @@ -13318,7 +13345,7 @@ static void blockExprStmts(GenZir* gz, Scope* scope, // defer/errdefer (AstGen.zig:2580-2581, deferStmt:3116-3187). case AST_NODE_DEFER: case AST_NODE_ERRDEFER: { - if (defer_idx >= 128 || val_idx >= 128) { + if (defer_idx >= max_scopes || val_idx >= max_scopes) { SET_ERROR(ag); break; } @@ -13455,6 +13482,9 @@ static void blockExprStmts(GenZir* gz, Scope* scope, if (!noreturn_stmt) { genDefers(gz, scope, cur_scope, DEFER_NORMAL_ONLY); } + free(val_scopes); + free(ptr_scopes); + free(defer_scopes); } // --- fullBodyExpr (AstGen.zig:2358) ---