wcc_ww/cgen: #60+#79 alias-NAMED array/slice ELEMENT paths read the chased tinfo — tichase lands, SEGV families graduate byte-id
One class: alias-blind base+esz at the array/slice ELEMENT paths — index read/write, slice-expr, for-range, and literal-init store. The wwstage cgen derived element size and base addressing from the type-AST tnode; an alias-typed base (`type arr = [4]int; let a: arr`) shows only the N_TNAME leaf, so esz fell to a sentinel (1 on the read side, 8 on the init-store side) and the base classified as a POINTER (MOVQ of array words, no IMULQ): m8b_idx1/range1 SEGV 139, m8b_slice1 silent-wrong past little-endian prefix-luck (m8c_slice1big exit 2), m7c global [2]row read SEGV via the alias-blind element-is-array classify, and (#79, ken F2a1 oracle) `type A=[4]u32; let a:A=[...]` stored MOVQ stride-8 over a stride-4 slot — elements 2/3 landed at 0(BP)/+8(BP), a saved-BP/RIP smash masked whenever esz==8. cstage reads everything off the chased stamped type (type_chase_named/ idx_eff, correct post-F1), so every fixed shape graduates ww-SEGV/silent-wrong -> 0/0 byte-id. New tichase() in cgenutil.ww: nil-passthrough transitive TY_NAMED peel, exact twin of cmd/wcc/type.c:160-162. Routed sites, all gated on the stamped type being TY_NAMED (non-alias paths byte-identical): - cgindex (cgenexpr.ww): elem facts (esz/signed/float/f32) off tichase(n.type_); etn falls back to n for the tagged/str/slice classify; LEAQ-vs-MOVQ base off the chased kind; elem-is-array supplemented by tinfoisarray(n.type_) for alias ELEMENTS (m7c). - cgassign N_INDEX store + compound arms (cgenexpr.ww): esz + elemtn=lhs (the stamped-element idiom of the N_DOT/N_INDEX arms); chased-kind base classify at all four LEAQ/MOVQ sites. - cgslice + cgbasecap (cgenexpr.ww): esz, base classify, default-hi (TY_ARRAY -> $alen / TY_SLICE|TY_STR -> +8 len), cap word at +16; global-str cap keeps the #73 carve-out. - cgforrange (cgenstmt.ww, cross-file leg: the range pin cannot green without it): esz, element-node synthesis off .sub (FC0 precedent), isarr/isslicestr classify, alen off the chased tinfo. - cgarrlitfillbp (cgenstmt.ww, #79): an alias [count]T arrtn is the N_TNAME leaf (elemn nil) — synthesise the element node off the chased sub so the existing prim/agg/slice/tagged/narrow dispatch works unchanged; `...` repeat bound off the chased alen (cstage cg_arrlit_fill_bp receives the pre-chased bu and reads bu->alen). #8-PAIR COVERAGE: this is the STORE half of #8's two size-sources. The elemsizeofc READ half chases the ELEMENT internally (idxeffti + esub peel, the #8 fix) but NOT an alias-typed INDEXABLE node — that leg is covered at its #60-family call sites by the gates above (cgindex/cgslice/store/compound/cgforrange/pusharg). Remaining alias-blind elemsizeofc callers are enumerated as residuals below. - bare-let classify (cgenstmt.ww, #79 rider): `let a: arrk;` with an alias-to-array type took the composite zero-fill cstage doesn't emit (cstage keys the no-init shape on the chased lu->kind: arrays keep the per-index-write contract; an 8B alias-array still falls to the single MOVQ $0 arm). Required for the loopfill_1024 pin's byte-id; closes the array kind of the uninit-alias divergence. - pusharg N_SLICE (cgenutil.ww, pulled in by the same pin rule: the 944 slice_of_alias_arg row is a distinct lowering from cgslice): esz, base classify, default-hi. Tests: new 944_alias_idx_family_run (19 rows: idx/slice/range/init controls + 1-level + 2-level + decl-order permutations + index store + compound (+=, *=) + #79 [4]u32 literal-init + alias `[v...]` repeat + uninit [1024] loop-fill + slice1big (1000 elems, values >255, LAST-element readback, default-hi, .cap, range count) + re-slice of an alias slice + range over an alias slice + m7c global 2D + GLOBAL alias-slice indexed read + slice-as-call-arg; dual-stage run + per-row byte-id; LAST elements asserted throughout). The six 944_alias_accept_run rows citing "#60 (F2 batch 1)" flip K_RUN_CS -> K_RUN (incl. slicefield_wholeread_2lvl: its 738d7f4-era receive-spine divergence no longer reproduces at the F1-merged base, verified byte-id + 0/0). 989_lib_byteid checked: no DIVERGE entry graduates (the test fails loudly on graduation; lib has no alias-base consumers — the shape SEGVed before this fix). NOT pinned (g-fold territory, #77/#78): direct alias-typed global ARRAY rows. Expected state probe-verified UNCHANGED by this diff: `let g: arr = [...]` -> ww link-ERR (no DATA emitted), cs 1-level runs 0, cs 2-level runs WRONG (silent). The alias-GLOBAL base legs added here (isglobalarr reclassify, global default-hi/cap) are cs-aligned but runtime-unreachable until the DATA emit lands. Residuals filed with the team: alias-blind elemsizeofc callers not in the #60 pin family — cgun &a[i] addr-of (cgenexpr.ww:4638 region, task #82), append() on an alias-typed slice local (:5287), `alloc([], n)` into an alias-slice let (cgenstmt.ww:2159), arr[i].field= float store (:8536); tagged-element READ under an alias base keeps the ident-arm nullable semantics; checker asserttyped on `untyped_lit * rangevar` over an alias slice (pre-existing, check.ww is batch 4, task #80); uninit alias-to-STRUCT zero-fill unchanged (correct: cstage fills composites); range-destructure over alias-to-tuple-slice. selfhost/cmd/{w6c,wwdump}/main.combined.ww regenerated (cgen*.ww are embedded sources).
This commit is contained in:
@@ -1727,6 +1727,13 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
// class; sentinel 754).
|
||||
let elemisstr: bool = false;
|
||||
let elemisslice: bool = false;
|
||||
// #60 (alias arc #5): the base's declared type is an N_IDENT alias
|
||||
// (`type arr = [4]int`). The tnode walks below see only the N_TNAME
|
||||
// leaf — esz fell to the 1-sentinel and the base classified as a
|
||||
// POINTER (MOVQ + no IMULQ → SEGV / prefix-luck reads). Set once
|
||||
// here, consumed by the elem-fact override, the etn fallback and
|
||||
// the LEAQ-vs-MOVQ base classify.
|
||||
let basealias: bool = false;
|
||||
let baselocal: *local = nil;
|
||||
// Global `[N]T` array or `*T` pointer used as an index base.
|
||||
// The local-ident lookup above misses it; we need LEAQ name(SB)
|
||||
@@ -1787,6 +1794,42 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};
|
||||
};
|
||||
// #60: element facts off the chased checker-stamped
|
||||
// tinfos — cstage reads them via type_chase_named/
|
||||
// idx_eff uniformly (cmd/w6c/cgen.c N_INDEX).
|
||||
let bt60: *tinfo = base.type_: *tinfo;
|
||||
if (bt60 != nil) {
|
||||
if (bt60.kind == tykind.TY_NAMED) { basealias = true; };
|
||||
};
|
||||
if (basealias) {
|
||||
let et60: *tinfo = tichase(n.type_: *tinfo);
|
||||
if (et60 != nil) {
|
||||
esz = et60.size: i32;
|
||||
signed_elem = typeissigned(et60);
|
||||
float_elem = typeisfloat(et60);
|
||||
f32_elem = typeisf32(et60);
|
||||
};
|
||||
// global base: array-vs-pointer re-keyed off the
|
||||
// chased BASE kind (cstage isglobal && u->kind ==
|
||||
// TY_ARRAY → LEAQ). Runtime-unreachable until the
|
||||
// alias-typed global DATA emit lands (#77/#78);
|
||||
// kept so the read leg is already cs-aligned.
|
||||
if (isglobalarr || isglobalptr) {
|
||||
let bu60: *tinfo = tichase(bt60);
|
||||
if (bu60 != nil) {
|
||||
isglobalarr = bu60.kind == tykind.TY_ARRAY;
|
||||
isglobalptr = !isglobalarr;
|
||||
};
|
||||
};
|
||||
};
|
||||
// Alias-typed ELEMENT under an ident base (`[2]row`,
|
||||
// row = [3]int): elemisarrayc's node walk can't see
|
||||
// through the element's N_TNAME — the chased stamped
|
||||
// element tinfo is the authority (cstage gates on
|
||||
// esubu = type_chase_named(esub) == TY_ARRAY).
|
||||
if (!elem_isarray) {
|
||||
elem_isarray = tinfoisarray(n.type_: *tinfo);
|
||||
};
|
||||
} else { if (base.kind == nkind.N_DOT
|
||||
|| (base.kind == nkind.N_UN && base.op == tkind.TK_STAR)) {
|
||||
// `s.ptr[i]` / struct-field index: stride is the
|
||||
@@ -1840,6 +1883,11 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
} else {
|
||||
etn = idxelemtn(letvartnode(c, base.str));
|
||||
};
|
||||
// #60: an alias-NAMED base has no element tnode
|
||||
// (idxelemtn sees the N_TNAME leaf, nil) — classify
|
||||
// off the stamped index-result n.type_, the same
|
||||
// source the N_DOT/N_INDEX arms read.
|
||||
if (basealias) { etn = n; };
|
||||
if (istaggedtype(c, etn)) {
|
||||
if (!isnullabletype(etn)) {
|
||||
elem_tagged = true;
|
||||
@@ -1946,6 +1994,12 @@ fn cgindex(c: *cgen, n: *node) void = {
|
||||
let tn: *node = baselocal.tnode;
|
||||
let isarray: bool = false;
|
||||
if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; };
|
||||
// #60: alias-NAMED base — LEAQ-vs-MOVQ off the chased stamped
|
||||
// kind (cstage u->kind == TY_ARRAY, cmd/w6c/cgen.c N_INDEX).
|
||||
if (basealias) {
|
||||
let bu60: *tinfo = tichase(base.type_: *tinfo);
|
||||
if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; };
|
||||
};
|
||||
if (isarray) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitoff(baselocal.off: i64);
|
||||
@@ -2116,6 +2170,31 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = {
|
||||
return true;
|
||||
};
|
||||
};
|
||||
// #60: alias-NAMED base — chased kind (cstage cg_base_cap
|
||||
// receives bu pre-chased by the N_SLICE arm, cgen.c:1888).
|
||||
let bt60: *tinfo = base.type_: *tinfo;
|
||||
if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) {
|
||||
let bu60: *tinfo = tichase(bt60);
|
||||
if (bu60 != nil) {
|
||||
if (bu60.kind == tykind.TY_ARRAY) {
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(bu60.alen: i64);
|
||||
emitline(", ");
|
||||
emitline(dst);
|
||||
emitline("\n");
|
||||
return true;
|
||||
};
|
||||
if (bu60.kind == tykind.TY_SLICE
|
||||
|| bu60.kind == tykind.TY_STR) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff((baselocal.off + 16): i64);
|
||||
emitline("(BP), ");
|
||||
emitline(dst);
|
||||
emitline("\n");
|
||||
return true;
|
||||
};
|
||||
};
|
||||
};};
|
||||
return false;
|
||||
};
|
||||
let gt: *node = letvartnode(c, base.str);
|
||||
@@ -2144,6 +2223,36 @@ fn cgbasecap(c: *cgen, base: *node, dst: str) bool = {
|
||||
emitline("\n");
|
||||
return true;
|
||||
};
|
||||
// #60: alias-NAMED global base — chased kind; global STR keeps
|
||||
// the #73 cap=len carve-out (cstage isglobal && TY_STR → 0).
|
||||
// Runtime-unreachable until #77/#78 global DATA.
|
||||
let gbt60: *tinfo = base.type_: *tinfo;
|
||||
if (gbt60 != nil) { if (gbt60.kind == tykind.TY_NAMED) {
|
||||
let gbu60: *tinfo = tichase(gbt60);
|
||||
if (gbu60 != nil) {
|
||||
if (gbu60.kind == tykind.TY_ARRAY) {
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(gbu60.alen: i64);
|
||||
emitline(", ");
|
||||
emitline(dst);
|
||||
emitline("\n");
|
||||
return true;
|
||||
};
|
||||
if (gbu60.kind == tykind.TY_SLICE) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymname(c, base.str);
|
||||
emitline("(SB), ");
|
||||
emitline(dst);
|
||||
emitline("\n");
|
||||
emitline("\tMOVQ\t16(");
|
||||
emitline(dst);
|
||||
emitline("), ");
|
||||
emitline(dst);
|
||||
emitline("\n");
|
||||
return true;
|
||||
};
|
||||
};
|
||||
};};
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -2195,6 +2304,20 @@ fn cgslice(c: *cgen, n: *node) void = {
|
||||
if (base != nil) { if (base.kind == nkind.N_ARRLIT) {
|
||||
arrlittn = base.lhs;
|
||||
};};
|
||||
// #60 (alias arc #5): alias-NAMED N_IDENT base — the tnode reads
|
||||
// below see only the N_TNAME leaf (esz 1-sentinel, MOVQ base,
|
||||
// $0 default-hi, cap=len). All four reads re-key off the chased
|
||||
// stamped tinfo, mirroring cstage N_SLICE's single
|
||||
// bu = type_chase_named(base->type) source (cmd/w6c/cgen.c).
|
||||
let basealias: bool = false;
|
||||
let bu60: *tinfo = nil;
|
||||
if (base != nil) { if (base.kind == nkind.N_IDENT) {
|
||||
let bt60: *tinfo = base.type_: *tinfo;
|
||||
if (bt60 != nil) { if (bt60.kind == tykind.TY_NAMED) {
|
||||
basealias = true;
|
||||
bu60 = tichase(bt60);
|
||||
};};
|
||||
};};
|
||||
// esz from the type table for an N_IDENT base (#76; mirrors the
|
||||
// cgindex idiom) or an N_DOT array/slice-field base (#252: scale by
|
||||
// the field's element width, not esz=1 — silently wrong for non-u8).
|
||||
@@ -2209,6 +2332,10 @@ fn cgslice(c: *cgen, n: *node) void = {
|
||||
} else { if (arrlittn != nil) {
|
||||
esz = elemsizeofc(c, arrlittn);
|
||||
};};};};
|
||||
if (bu60 != nil) {
|
||||
let es60: *tinfo = tichase(bu60.sub);
|
||||
if (es60 != nil) { esz = es60.size: i32; };
|
||||
};
|
||||
// base address
|
||||
if (baselocal != nil) {
|
||||
let tn: *node = baselocal.tnode;
|
||||
@@ -2216,6 +2343,8 @@ fn cgslice(c: *cgen, n: *node) void = {
|
||||
if (tn != nil) {
|
||||
if (tn.kind == nkind.N_TARRAY) { isarray = true; };
|
||||
};
|
||||
// #60: alias-NAMED base — chased kind (see cgindex twin).
|
||||
if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; };
|
||||
if (isarray) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitoff(baselocal.off: i64);
|
||||
@@ -2229,7 +2358,11 @@ fn cgslice(c: *cgen, n: *node) void = {
|
||||
// Top-level let: [N]T → LEAQ name(SB); pointer/slice/str
|
||||
// → MOVQ name(SB) (the symbol holds the {ptr,len,cap} or
|
||||
// {ptr,len} or pointer value).
|
||||
if (globaltn.kind == nkind.N_TARRAY) {
|
||||
let gisarr: bool = globaltn.kind == nkind.N_TARRAY;
|
||||
// #60: alias-NAMED base — chased kind; runtime-unreachable
|
||||
// until #77/#78 global DATA (see cgindex twin).
|
||||
if (bu60 != nil) { gisarr = bu60.kind == tykind.TY_ARRAY; };
|
||||
if (gisarr) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymname(c, globalname);
|
||||
emitline("(SB), AX\n");
|
||||
@@ -2308,6 +2441,23 @@ fn cgslice(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};};};
|
||||
};
|
||||
// #60: alias-NAMED base default-hi — chased kind (cstage
|
||||
// N_SLICE hi-default reads bu uniformly: TY_ARRAY → $alen,
|
||||
// TY_SLICE/TY_STR → len word at +8).
|
||||
if (!handled && bu60 != nil) {
|
||||
if (bu60.kind == tykind.TY_ARRAY) {
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(bu60.alen: i64);
|
||||
emitline(", AX\n");
|
||||
handled = true;
|
||||
} else { if (bu60.kind == tykind.TY_SLICE
|
||||
|| bu60.kind == tykind.TY_STR) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitoff((baselocal.off + 8): i64);
|
||||
emitline("(BP), AX\n");
|
||||
handled = true;
|
||||
};};
|
||||
};
|
||||
if (!handled) { emitline("\tMOVQ\t$0, AX\n"); };
|
||||
} else { if (globaltn != nil) {
|
||||
let handled: bool = false;
|
||||
@@ -2328,6 +2478,24 @@ fn cgslice(c: *cgen, n: *node) void = {
|
||||
emitline("\tMOVQ\t8(CX), AX\n");
|
||||
handled = true;
|
||||
};};
|
||||
// #60: alias-NAMED global base default-hi — chased kind;
|
||||
// runtime-unreachable until #77/#78 global DATA (cstage
|
||||
// emits LEAQ+8 for global SLICE/STR alike).
|
||||
if (!handled && bu60 != nil) {
|
||||
if (bu60.kind == tykind.TY_ARRAY) {
|
||||
emitline("\tMOVQ\t$");
|
||||
emitint(bu60.alen: i64);
|
||||
emitline(", AX\n");
|
||||
handled = true;
|
||||
} else { if (bu60.kind == tykind.TY_SLICE
|
||||
|| bu60.kind == tykind.TY_STR) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymname(c, globalname);
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\tMOVQ\t8(CX), AX\n");
|
||||
handled = true;
|
||||
};};
|
||||
};
|
||||
if (!handled) { emitline("\tMOVQ\t$0, AX\n"); };
|
||||
} else { if (dotbu != nil && dotbu.kind == tykind.TY_ARRAY) {
|
||||
// #252: default-hi `s.obuf[lo:]` on a struct array-field →
|
||||
@@ -7647,6 +7815,7 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
let globalname: str;
|
||||
globalname.ptr = nil; globalname.len = 0;
|
||||
let elemtn: *node = nil;
|
||||
let basealias: bool = false;
|
||||
if (base != nil) {
|
||||
if (base.kind == nkind.N_IDENT) {
|
||||
let bn: str = base.str;
|
||||
@@ -7720,6 +7889,37 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};};};
|
||||
};
|
||||
// #60 (write spine): alias-NAMED N_IDENT base — the
|
||||
// tnode walk above is blind (esz 1-sentinel, elemtn
|
||||
// nil → pointer-treated base, wrong-stride store).
|
||||
// Adopt the stamped-element idiom of the N_DOT/
|
||||
// N_INDEX arms (lhs.type_ IS the element tinfo);
|
||||
// cstage N_INDEX store reads idx_eff(base->type)->sub
|
||||
// uniformly (cmd/w6c/cgen.c:3517-3518).
|
||||
if (base != nil) {
|
||||
if (base.kind == nkind.N_IDENT) {
|
||||
let bt60: *tinfo = base.type_: *tinfo;
|
||||
if (bt60 != nil) {
|
||||
if (bt60.kind == tykind.TY_NAMED) { basealias = true; };
|
||||
};
|
||||
if (basealias) {
|
||||
let et60: *tinfo = tichase(lhs.type_: *tinfo);
|
||||
if (et60 != nil) {
|
||||
esz = et60.size: i32;
|
||||
elemtn = lhs;
|
||||
};
|
||||
// see cgindex twin: cs-aligned, runtime-
|
||||
// unreachable until #77/#78 global DATA.
|
||||
if (isglobalarr || isglobalptr) {
|
||||
let bu60: *tinfo = tichase(bt60);
|
||||
if (bu60 != nil) {
|
||||
isglobalarr = bu60.kind == tykind.TY_ARRAY;
|
||||
isglobalptr = !isglobalarr;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
// Tagged-union element: materialize source in a shared
|
||||
// scratch slot via cgwidentaggedstore (handles struct /
|
||||
// str / scalar / subset / nullable variants uniformly),
|
||||
@@ -7765,6 +7965,12 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
isarr = true;
|
||||
};
|
||||
};
|
||||
// #60: alias-NAMED base — chased kind
|
||||
// (see cgindex twin).
|
||||
if (basealias) {
|
||||
let bu60: *tinfo = tichase(base.type_: *tinfo);
|
||||
if (bu60 != nil) { isarr = bu60.kind == tykind.TY_ARRAY; };
|
||||
};
|
||||
if (isarr) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitoff(baselocal.off: i64);
|
||||
@@ -7887,6 +8093,11 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
let tn2: *node = baselocal.tnode;
|
||||
let isarr2: bool = false;
|
||||
if (tn2 != nil) { if (tn2.kind == nkind.N_TARRAY) { isarr2 = true; }; };
|
||||
// #60: alias-NAMED base — chased kind (see cgindex twin).
|
||||
if (basealias) {
|
||||
let bu60: *tinfo = tichase(base.type_: *tinfo);
|
||||
if (bu60 != nil) { isarr2 = bu60.kind == tykind.TY_ARRAY; };
|
||||
};
|
||||
if (isarr2) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitoff(baselocal.off: i64);
|
||||
@@ -8014,6 +8225,11 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
let tn: *node = baselocal.tnode;
|
||||
let isarray: bool = false;
|
||||
if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; };
|
||||
// #60: alias-NAMED base — chased kind (see cgindex twin).
|
||||
if (basealias) {
|
||||
let bu60: *tinfo = tichase(base.type_: *tinfo);
|
||||
if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; };
|
||||
};
|
||||
if (isarray) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitoff(baselocal.off: i64);
|
||||
@@ -8155,6 +8371,31 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
};
|
||||
};};};
|
||||
};
|
||||
// #60 (compound spine): alias-NAMED N_IDENT base —
|
||||
// same stamped-element adoption as the store arm.
|
||||
let basealias: bool = false;
|
||||
if (base != nil) {
|
||||
if (base.kind == nkind.N_IDENT) {
|
||||
let bt60: *tinfo = base.type_: *tinfo;
|
||||
if (bt60 != nil) {
|
||||
if (bt60.kind == tykind.TY_NAMED) { basealias = true; };
|
||||
};
|
||||
if (basealias) {
|
||||
let et60: *tinfo = tichase(lhs.type_: *tinfo);
|
||||
if (et60 != nil) {
|
||||
esz = et60.size: i32;
|
||||
elemtn = lhs;
|
||||
};
|
||||
if (isglobalarr || isglobalptr) {
|
||||
let bu60: *tinfo = tichase(bt60);
|
||||
if (bu60 != nil) {
|
||||
isglobalarr = bu60.kind == tykind.TY_ARRAY;
|
||||
isglobalptr = !isglobalarr;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
// #133-expanded: hard-error unwired payload kinds
|
||||
// LOUD (rule-7) — replaces prior silent skip.
|
||||
if (elemtn != nil) {
|
||||
@@ -8201,6 +8442,11 @@ fn cgassign(c: *cgen, n: *node) void = {
|
||||
let tn: *node = baselocal.tnode;
|
||||
let isarray: bool = false;
|
||||
if (tn != nil) { if (tn.kind == nkind.N_TARRAY) { isarray = true; }; };
|
||||
// #60: alias-NAMED base — chased kind (see cgindex twin).
|
||||
if (basealias) {
|
||||
let bu60: *tinfo = tichase(base.type_: *tinfo);
|
||||
if (bu60 != nil) { isarray = bu60.kind == tykind.TY_ARRAY; };
|
||||
};
|
||||
if (isarray) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitoff(baselocal.off: i64);
|
||||
|
||||
Reference in New Issue
Block a user