From 4da900cbb88bb5bb53246dc96a550d16f52b3481 Mon Sep 17 00:00:00 2001 From: Motiejus Date: Tue, 3 Mar 2026 08:43:16 +0000 Subject: [PATCH] stage0: fix enum_literal to store string index, not djb2 hash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit zirEnumLiteral was storing simpleStringHash(name) — a djb2 hash — as the enum_literal IP key field. Upstream Zig stores a NullTerminatedString index (getOrPutString). All three read sites treat the field as a string table index and dereference it into ip->string_bytes, so the hash value caused silent out-of-bounds reads whenever enum_literal coercion, callconv, or signedness parsing were exercised. Replace simpleStringHash with ipGetOrPutString, matching upstream exactly. Co-Authored-By: Claude Sonnet 4.6 --- stage0/sema.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/stage0/sema.c b/stage0/sema.c index f591a28bb7..6de3160a2d 100644 --- a/stage0/sema.c +++ b/stage0/sema.c @@ -17,16 +17,6 @@ } \ } while (0) -// Simple djb2 hash for enum literal names. -static uint32_t simpleStringHash(const char* s) { - uint32_t h = 5381; - while (*s) { - h = h * 33 + (uint8_t)*s; - s++; - } - return h; -} - #define SEMA_AIR_INITIAL_CAP 256 #define SEMA_AIR_EXTRA_INITIAL_CAP 256 #define INST_MAP_INITIAL_CAP 32 @@ -9976,7 +9966,7 @@ static AirInstRef zirEnumLiteral(Sema* sema, uint32_t inst) { InternPoolKey key; memset(&key, 0, sizeof(key)); key.tag = IP_KEY_ENUM_LITERAL; - key.data.enum_literal = simpleStringHash(name); + key.data.enum_literal = ipGetOrPutString(sema->ip, name); return AIR_REF_FROM_IP(ipIntern(sema->ip, key)); }