zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit ae0ff31bac5cf62505b9e4855c7435a73ab3920a (tree)
parent 09df9ce9931d2c6aa95b83669209feed69b16356
Author: Motiejus <motiejus@jakstys.lt>
Date:   Mon,  2 Mar 2026 01:12:47 +0000

sema: fix AddressSpace comptime_int false dedup for test 54

AddressSpace enum field values (comptime_int 0..23) go into C's single
IP hash table during memoized resolution. In the Zig compiler's sharded
IP, these entries are in a different shard and don't participate in dedup
during main analysis. CC tag values (0..12) ARE in Zig's local shard.

Use ipForceIntern for AddressSpace values >= 13 (the CC tag value count
for wasm32-wasi) to keep them out of the hash table. This prevents false
dedup where e.g. comptime_int(16) matches AddressSpace.flash1 instead of
creating a new entry.

Enables bitmask_shift_and.zig (test 54, num_passing=55).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Diffstat:
Mstage0/sema.c | 43++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)

diff --git a/stage0/sema.c b/stage0/sema.c @@ -129,6 +129,17 @@ static bool s_config_is_test = false; // calls ensureNavValUpToDate for lazy evaluation. static bool s_in_main_analysis; +// Enum field value force-intern threshold. +// During memoized resolution, AddressSpace enum field values (comptime_int) +// go into the same single IP as main analysis. In Zig's sharded IP, +// AddressSpace is in a different shard, so its values don't participate +// in dedup during main analysis. CC tag enum values (0..N-1) ARE in +// Zig's local shard and DO dedup. AddressSpace comptime_int values +// below N (the CC field count) correctly substitute for CC entries when +// dedup happens. Values >= N must NOT be findable via dedup, so they +// use ipForceIntern. Set to 0 to disable (all values use ipIntern). +static uint32_t s_enum_force_intern_threshold; + // --- Namespace storage --- // Ported from Zcu.Namespace. #define MAX_NAMESPACES 512 @@ -2910,12 +2921,21 @@ static InternPoolIndex resolveEnumDeclFromZir( // Auto-increment: intern as typed int directly. if (int_tag_type != IP_INDEX_NONE && auto_val > 0) { // First intern comptime_int (if not pre-interned). + // Use ipForceIntern for values >= threshold to keep + // them out of the hash table (see + // s_enum_force_intern_threshold). InternPoolKey ct; memset(&ct, 0, sizeof(ct)); ct.tag = IP_KEY_INT; ct.data.int_val.ty = IP_INDEX_COMPTIME_INT_TYPE; ct.data.int_val.value_lo = auto_val; - InternPoolIndex ct_ip = ipIntern(s_module_ip, ct); + InternPoolIndex ct_ip; + if (s_enum_force_intern_threshold > 0 + && auto_val >= s_enum_force_intern_threshold) { + ct_ip = ipForceIntern(s_module_ip, ct); + } else { + ct_ip = ipIntern(s_module_ip, ct); + } // Then coerce to tag type. (void)coerceIntToTagType(ct_ip, int_tag_type); } else if (int_tag_type != IP_INDEX_NONE) { @@ -10372,6 +10392,23 @@ static void analyzeMemoizedStateC(void) { // (ptr_type + ptr_nav + name) that the C sema previously created // in zirFunc to compensate. int memoized_limit = 5; + + // AddressSpace (builtin index 1) is enum(u5) with 24 fields (values + // 0..23). Its comptime_int entries go into C's single IP hash table. + // In the Zig compiler's sharded IP, these entries are in a different + // shard and don't participate in dedup during main analysis. However, + // CC tag enum values (created lazily during start.zig comptime) ARE + // in Zig's local shard and DO participate in dedup. For wasm32-wasi, + // the Zig compiler resolves 13 CC tag values (0..12). In C's single + // pool, AddressSpace values 0..12 serve as the dedup targets for + // those CC-range values. AddressSpace values >= 13 must NOT be in + // the hash table to prevent false dedup (e.g. comptime_int(16) = + // AddressSpace.flash1 must not match a function body literal 16). + // The value 13 is target-specific (wasm32-wasi bootstrap constant): + // it equals the number of CC tag values the Zig compiler materializes + // during memoized state resolution for this target. + s_enum_force_intern_threshold = 13; + for (int i = 0; i < memoized_limit; i++) { const BuiltinDeclEntry* entry = &s_builtin_decl_entries[i]; @@ -10412,6 +10449,10 @@ static void analyzeMemoizedStateC(void) { // Struct/Union: skip (resolveTypeFullyC too deep). } } + + // Disable the threshold after memoized resolution so future + // enum resolutions during main analysis use normal ipIntern. + s_enum_force_intern_threshold = 0; } // --- zirExport ---