astgen: fix ptrTypeExpr addrspace, do_err_trace check, switchExpr capture, blockExprStmts heap alloc

- ptrTypeExpr: use addBuiltinValue + RL_COERCED_TY for addrspace (matching
  AstGen.zig:3880-3881) instead of RL_NONE_VAL
- do_err_trace: check ag->fn_block != NULL instead of ag->fn_ret_ty != 0 in
  ifExpr, orelseCatchExpr, switchExprErrUnion (matching Zig semantics)
- switchExpr: don't reset capture for underscore discards (AstGen.zig:7870)
- nodeIsTriviallyZero: handle prefixed zero forms (0b0, 0o0, 0x0, with
  underscores)
- blockExprStmts: heap-allocate scope arrays sized to stmt_count instead of
  fixed 128, fixing compile errors on large blocks (e.g. scalar.zig)
- build.zig: increase default test timeout from 10s to 300s
- Remove debug fprintf counters

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-17 05:30:35 +00:00
parent fbba8b99fd
commit 4cfde11ef0
2 changed files with 56 additions and 26 deletions

View File

@@ -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,

View File

@@ -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) ---