wcc: store to a global tagged-array element resolves the (SB) base (#16)

The indexed tagged-element assign arm computed its base without the
isglobal -> LEAQ name(SB) branch the scalar element arm already has, so
`gs[i] = v` on a global tagged array stored to a junk frame base and was
lost -- cstage rc=0 where wwstage (which has the branch) rc=42. Mirror
the scalar arm's base resolution; cstage aligns up to wwstage. Local
tagged arrays and scalar globals are unchanged.

The global tagged-array static initializer still mis-packs its DATA in
both stages -- a separate emitter path, filed as #19.
This commit is contained in:
2026-06-14 00:14:42 +09:00
parent 1074239859
commit 323607d1d0
3 changed files with 292 additions and 7 deletions

View File

@@ -6499,14 +6499,27 @@ cgexpr(Cg *c, Node *n, Local *locals)
ins2(c, A_MOVQ, aimm(ssz), areg(D_CX));
ins2(c, A_IMULQ, areg(D_CX), areg(D_AX));
}
if (base->kind == N_IDENT && is_arr) {
if (base->kind == N_IDENT) {
int boff = localfind(locals, base->str);
ins2(c, A_LEAQ, amem(D_BP, boff),
areg(D_BX));
} else if (base->kind == N_IDENT) {
int boff = localfind(locals, base->str);
ins2(c, A_MOVQ, amem(D_BP, boff),
areg(D_BX));
int isglobal = (boff == 0) &&
let_islet(base->str);
if (isglobal && is_arr) {
ins2(c, A_LEAQ,
masym(c, base->str),
areg(D_BX));
} else if (isglobal) {
ins2(c, A_MOVQ,
masym(c, base->str),
areg(D_BX));
} else if (is_arr) {
ins2(c, A_LEAQ,
amem(D_BP, boff),
areg(D_BX));
} else {
ins2(c, A_MOVQ,
amem(D_BP, boff),
areg(D_BX));
}
} else if (cg_dotbase_addr(c, base, D_BX, locals)) {
/* #259: N_DOT base resolved inline to the
* field address; cgexpr fallback would