commit db20fc90b2393d3bf552052ea1247a292c869a3d (tree)
parent 5faac5d0d8193153f24a4167b390d014fcfa0f21
Author: Motiejus Jakštys <motiejus@jakstys.lt>
Date: Thu, 26 Feb 2026 05:21:49 +0000
sema: fix ZIR→IP signedness inversion, resolve Signedness/AddressSpace types
ZIR uses the Zig Signedness enum convention (signed=0, unsigned=1) while
the InternPool uses the inverted convention (unsigned=0, signed=1). Fix
both places that read signedness from ZIR: resolveEnumDeclFromZir (for
explicit enum tag types) and zirIntType (for int_type instructions).
Add resolveBuiltinDeclTypes() to resolve BuiltinDecl types from
std.builtin in order, matching Sema.zig's analyzeMemoizedState. Currently
resolves Signedness and AddressSpace, creating IP entries $213-$251.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat:
1 file changed, 38 insertions(+), 4 deletions(-)
diff --git a/stage0/sema.c b/stage0/sema.c
@@ -2775,13 +2775,16 @@ static InternPoolIndex resolveEnumDeclFromZir(
if (tt_inst < zir->inst_len
&& zir->inst_tags[tt_inst] == ZIR_INST_INT_TYPE) {
uint16_t bits = zir->inst_datas[tt_inst].int_type.bit_count;
- uint8_t signedness
+ // ZIR uses Zig Signedness enum: signed=0, unsigned=1.
+ // IP uses: unsigned=0, signed=1. Invert.
+ uint8_t zir_sign
= zir->inst_datas[tt_inst].int_type.signedness;
+ uint8_t ip_sign = (zir_sign == 0) ? 1 : 0;
InternPoolKey itk;
memset(&itk, 0, sizeof(itk));
itk.tag = IP_KEY_INT_TYPE;
itk.data.int_type.bits = bits;
- itk.data.int_type.signedness = signedness;
+ itk.data.int_type.signedness = ip_sign;
int_tag_type = ipIntern(s_module_ip, itk);
}
}
@@ -3073,6 +3076,28 @@ static void internStringLiteral(const char* str) {
(void)ipIntern(s_module_ip, bytes2_key);
}
+// --- resolveBuiltinDeclTypes ---
+// Resolve BuiltinDecl types from std.builtin namespace.
+// Ported from Sema.zig analyzeMemoizedState (main stage).
+// This resolves types in BuiltinDecl order: Signedness, AddressSpace,
+// CallingConvention, etc.
+static void resolveBuiltinDeclTypes(uint32_t builtin_ns_idx) {
+ // BuiltinDecl types in order (main stage only).
+ // Each is looked up in std.builtin and resolved.
+ static const char* const builtin_type_names[] = {
+ "Signedness",
+ "AddressSpace",
+ };
+ uint32_t n_types
+ = sizeof(builtin_type_names) / sizeof(builtin_type_names[0]);
+ for (uint32_t i = 0; i < n_types; i++) {
+ uint32_t nav
+ = findNavInNamespace(builtin_ns_idx, builtin_type_names[i]);
+ if (nav != UINT32_MAX)
+ (void)ensureNavValUpToDate(nav);
+ }
+}
+
// --- resolveStartComptimePreamble ---
// Create the IP entries that the Zig compiler generates when processing
// start.zig's comptime block. This block evaluates builtin.zig_backend
@@ -3194,6 +3219,12 @@ static void resolveStartComptimePreamble(void) {
// start.zig's else branch evaluates @hasDecl(root, "main") which
// triggers interning of the string literal "main".
internStringLiteral("main");
+
+ // --- $213+: BuiltinDecl type resolution ---
+ // The Zig compiler calls analyzeMemoizedState which resolves types
+ // from std.builtin in BuiltinDecl order. Port this by resolving each
+ // declaration via ensureNavValUpToDate.
+ resolveBuiltinDeclTypes(builtin_ns_idx);
}
// --- findDeclImportPathFromZir ---
@@ -9142,13 +9173,16 @@ static void zirUnreachable(Sema* sema, SemaBlock* block, uint32_t inst) {
// --- zirIntType ---
// Ported from src/Sema.zig zirIntType.
static AirInstRef zirIntType(Sema* sema, uint32_t inst) {
- uint8_t signedness = sema->code.inst_datas[inst].int_type.signedness;
+ // ZIR uses Zig Signedness enum: signed=0, unsigned=1.
+ // IP uses: unsigned=0, signed=1. Invert.
+ uint8_t zir_sign = sema->code.inst_datas[inst].int_type.signedness;
+ uint8_t ip_sign = (zir_sign == 0) ? 1 : 0;
uint16_t bit_count = sema->code.inst_datas[inst].int_type.bit_count;
InternPoolKey key;
memset(&key, 0, sizeof(key));
key.tag = IP_KEY_INT_TYPE;
key.data.int_type.bits = bit_count;
- key.data.int_type.signedness = signedness;
+ key.data.int_type.signedness = ip_sign;
return AIR_REF_FROM_IP(ipIntern(sema->ip, key));
}