stage0: pass store_to_pointer.zig (num_passing=31)
Fix three issues in zirFunc pre-creation to match Zig's funcCommon: 1. Resolve param types before func_type creation: iterate param_block and call resolveZirTypeRef/resolveZirTypeInst for each param's type body, creating IP entries (e.g. *u32) before the func_type entry. This matches the Zig compiler's funcCommon which evaluates param types before creating the func_type. 2. Use ipForceIntern for func_type: the C sema's func_type key only includes param_count (not actual param types), causing incorrect deduplication between functions with different param types but the same count. The upstream Zig IP includes param types, so different functions always get distinct func_types. ipForceIntern avoids the false dedup. 3. Fix sentinel=IP_INDEX_NONE in all ptr_type creation sites: 6 sites were using memset(0) which gives sentinel=0 instead of IP_INDEX_NONE (UINT32_MAX), preventing deduplication with correctly-created pointer types. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
/// `num_passing` controls how many files are tested and pre-generated.
|
||||
/// Both build.zig and stages_test.zig import this file.
|
||||
/// To enable more tests: just increment `num_passing`.
|
||||
pub const num_passing: usize = 30;
|
||||
pub const num_passing: usize = 31;
|
||||
|
||||
pub const files = [_][]const u8{
|
||||
"stage0/sema_tests/empty.zig",
|
||||
|
||||
@@ -8444,8 +8444,11 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
|
||||
ret_ty = resolved;
|
||||
}
|
||||
|
||||
// Count parameters from param_block (not the function body).
|
||||
// Count parameters and resolve their types from param_block.
|
||||
// Ported from Zir.getParamBody, matching ensureNavValUpToDate.
|
||||
// Param types must be resolved BEFORE func_type creation to
|
||||
// match the Zig compiler's funcCommon ordering (param type
|
||||
// IP entries precede func_type in the intern pool).
|
||||
uint32_t param_count = 0;
|
||||
{
|
||||
uint32_t pi = sema->code.inst_datas[inst].pl_node.payload_index;
|
||||
@@ -8454,11 +8457,32 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
|
||||
uint32_t pb_len = 0;
|
||||
getParamBody(sema, pb_inst, &pb_body, &pb_len);
|
||||
for (uint32_t pbi = 0; pbi < pb_len; pbi++) {
|
||||
ZirInstTag ptag = sema->code.inst_tags[pb_body[pbi]];
|
||||
if (ptag == ZIR_INST_PARAM || ptag == ZIR_INST_PARAM_COMPTIME
|
||||
|| ptag == ZIR_INST_PARAM_ANYTYPE
|
||||
|| ptag == ZIR_INST_PARAM_ANYTYPE_COMPTIME) {
|
||||
param_count++;
|
||||
uint32_t param_inst = pb_body[pbi];
|
||||
ZirInstTag ptag = sema->code.inst_tags[param_inst];
|
||||
if (ptag != ZIR_INST_PARAM && ptag != ZIR_INST_PARAM_COMPTIME
|
||||
&& ptag != ZIR_INST_PARAM_ANYTYPE
|
||||
&& ptag != ZIR_INST_PARAM_ANYTYPE_COMPTIME)
|
||||
continue;
|
||||
param_count++;
|
||||
// Resolve param type to create IP entries in the
|
||||
// correct order (before func_type).
|
||||
uint32_t pp
|
||||
= sema->code.inst_datas[param_inst].pl_tok.payload_index;
|
||||
uint32_t type_packed = sema->code.extra[pp + 1];
|
||||
uint32_t type_body_len = type_packed & 0x7FFFFFFF;
|
||||
if (type_body_len == 1) {
|
||||
// break_inline with operand = type ref.
|
||||
uint32_t bi2 = sema->code.extra[pp + 2];
|
||||
if (sema->code.inst_tags[bi2] == ZIR_INST_BREAK_INLINE) {
|
||||
ZirInstRef tref
|
||||
= sema->code.inst_datas[bi2].break_data.operand;
|
||||
(void)resolveZirTypeRef(
|
||||
&sema->code, tref, ns_idx, sema->file_idx);
|
||||
}
|
||||
} else if (type_body_len == 2) {
|
||||
uint32_t ti = sema->code.extra[pp + 2];
|
||||
(void)resolveZirTypeInst(
|
||||
&sema->code, ti, ns_idx, sema->file_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8538,13 +8562,18 @@ static void zirFunc(Sema* sema, SemaBlock* block, uint32_t inst) {
|
||||
}
|
||||
|
||||
// Create function type IP entry.
|
||||
// Use ipForceIntern because the C sema's func_type key doesn't
|
||||
// include actual parameter types (only param_count), so ipIntern
|
||||
// would incorrectly deduplicate functions with different param
|
||||
// types but the same (ret, param_count, cc). The upstream Zig IP
|
||||
// includes param types in the key, avoiding this false dedup.
|
||||
InternPoolKey ftype_key;
|
||||
memset(&ftype_key, 0, sizeof(ftype_key));
|
||||
ftype_key.tag = IP_KEY_FUNC_TYPE;
|
||||
ftype_key.data.func_type.return_type = ret_ty;
|
||||
ftype_key.data.func_type.param_count = param_count;
|
||||
ftype_key.data.func_type.cc = cc;
|
||||
InternPoolIndex func_type_ip = ipIntern(sema->ip, ftype_key);
|
||||
InternPoolIndex func_type_ip = ipForceIntern(sema->ip, ftype_key);
|
||||
|
||||
// Create func_decl entry (must follow func_type immediately).
|
||||
// Find the nav for this function declaration.
|
||||
|
||||
Reference in New Issue
Block a user