wcc_ww/check: W3 #105 nested-arrlit gate chases the alias elem type

checkarrlitfits' nested recursion keyed on the raw elemtn kind; a
named-alias element type ([2]row, row=[2]int) arrives as N_TNAME, so
the inner overlong literal skipped the count+range checks and the
module static-DATA route emitted silently TRUNCATED data (ken's
m7c_global: DATAW 1,2,4,5 — exit-masked once the #60 read fix removed
the segv; cstage loud-rejects every spelling via its typed-literal
assignability net). #105: the W1 fill gate never runs on this route,
severity raised post-#60.

Fix: chase elemtn through resolvealias (transitive) at the recursion
gate — alias spellings of any depth take the same checks as the
direct shape at all four contexts funneling through the choke point
(module let / local let / def / struct-field). A direct N_TARRAY
passes through resolvealias unchanged, so accepted shapes are
byte-identical base→tip (m7c_global_ok + exact-fit alias
field/def/2lvl probed ASM-ID vs a base scratch build). The m7/m7b
local overlong rows stay loud, now via the earlier count-naming
checker diagnostic instead of the cgen #270-1c fatal. The
out-of-range narrow inner element louds "array element out of
range" exactly as the direct spelling already did on wwstage.

808_arrlit_overlong: 37 -> 50 checks (+1 accept control
alias_exact_module = ken's m7c_global_ok with a byte-id cell, +4 loud
flips alias_nested_{module,2lvl,def,field} pinning per-stage texts,
+1 REVIEW AMENDMENT alias_nested_local pinning the m7/m7b text move
— pre-fix ww was loud via the late cgen #270-1c fatal; the row reds
if the diag regresses off the checker count text).
989 ratchet zero flips — no lib module-level literal trips the gate.

Filed sibling, not folded: OUTER alias-of-array overlong
(let g: arr = [5 elems], arr=[4]int) still ww-silent-truncates at the
alias-blind call-site N_TARRAY gates; cs louds with the count text.
This commit is contained in:
2026-06-06 06:54:41 +09:00
parent 4b118fa8f8
commit 329481c920
4 changed files with 121 additions and 13 deletions

View File

@@ -14423,11 +14423,17 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = {
// which wwstage's untyped elements have no analog of; the
// silent accept emitted corrupted DATA / smashed frames.
// Recursion through the one choke point closes any depth.
// A named-alias element type ([2]row) still bypasses — the
// elemtn node is N_IDENT, not N_TARRAY — task #16.
if (elemtn != nil && elemtn.kind == nkind.N_TARRAY
// #105: a named-alias element type ([2]row) arrives as
// N_TNAME and bypassed the kind test — the module
// static-DATA emitter then silently TRUNCATED the overlong
// inner literal (exit-masked once the #60 read fix removed
// the segv). resolvealias is transitive, so alias spellings
// of any depth take the same recursion; a direct N_TARRAY
// passes through unchanged.
let eltr: *node = resolvealias(c, elemtn);
if (eltr != nil && eltr.kind == nkind.N_TARRAY
&& ev != nil && ev.kind == nkind.N_ARRLIT) {
checkarrlitfits(c, elemtn, ev);
checkarrlitfits(c, eltr, ev);
e = e.next;
continue;
};

View File

@@ -4142,11 +4142,17 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = {
// which wwstage's untyped elements have no analog of; the
// silent accept emitted corrupted DATA / smashed frames.
// Recursion through the one choke point closes any depth.
// A named-alias element type ([2]row) still bypasses — the
// elemtn node is N_IDENT, not N_TARRAY — task #16.
if (elemtn != nil && elemtn.kind == nkind.N_TARRAY
// #105: a named-alias element type ([2]row) arrives as
// N_TNAME and bypassed the kind test — the module
// static-DATA emitter then silently TRUNCATED the overlong
// inner literal (exit-masked once the #60 read fix removed
// the segv). resolvealias is transitive, so alias spellings
// of any depth take the same recursion; a direct N_TARRAY
// passes through unchanged.
let eltr: *node = resolvealias(c, elemtn);
if (eltr != nil && eltr.kind == nkind.N_TARRAY
&& ev != nil && ev.kind == nkind.N_ARRLIT) {
checkarrlitfits(c, elemtn, ev);
checkarrlitfits(c, eltr, ev);
e = e.next;
continue;
};

View File

@@ -14423,11 +14423,17 @@ fn checkarrlitfits(c: *checker, arrtn: *node, rhs: *node) void = {
// which wwstage's untyped elements have no analog of; the
// silent accept emitted corrupted DATA / smashed frames.
// Recursion through the one choke point closes any depth.
// A named-alias element type ([2]row) still bypasses — the
// elemtn node is N_IDENT, not N_TARRAY — task #16.
if (elemtn != nil && elemtn.kind == nkind.N_TARRAY
// #105: a named-alias element type ([2]row) arrives as
// N_TNAME and bypassed the kind test — the module
// static-DATA emitter then silently TRUNCATED the overlong
// inner literal (exit-masked once the #60 read fix removed
// the segv). resolvealias is transitive, so alias spellings
// of any depth take the same recursion; a direct N_TARRAY
// passes through unchanged.
let eltr: *node = resolvealias(c, elemtn);
if (eltr != nil && eltr.kind == nkind.N_TARRAY
&& ev != nil && ev.kind == nkind.N_ARRLIT) {
checkarrlitfits(c, elemtn, ev);
checkarrlitfits(c, eltr, ev);
e = e.next;
continue;
};