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:
@@ -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,
|
||||
|
||||
@@ -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) ---
|
||||
|
||||
Reference in New Issue
Block a user