w6c+wwstage: aggregate let-init copy from a struct-DEF global (#268 reviewer)

The fold-1b unified arm (bb2f4e1) added an N_IDENT addressable-rhs source
setup, but the two stages gated the GLOBAL case differently: cstage used
let_islet || def_isarraydef, wwstage used isletvar || deflookup (ANY def).
On a struct-typed `def` used as an aggregate-copy rhs (`let c: T = G`)
wwstage copied the whole value (correct) while cstage truncated to the 8B
scalar tail — a cs!=ww divergence (rule-10). A struct-LET global already
copies on both, so the def gap was also an internal cstage inconsistency.

Struct defs are first-class laid-out aggregates (DATA storage + field
load, #129 A.2/A.3), so converge on the correct full copy on both: add
def_isstructdef to cstage's predicate and replace wwstage's broad
deflookup with the def_is{array,struct}def pairing already held identical
in defisaddressable. 949 +2 rows (array-def + struct-def global, full
readback, byteid=1).
This commit is contained in:
2026-06-02 11:37:34 +09:00
parent bb2f4e1dfe
commit 35b517ca3e
5 changed files with 74 additions and 7 deletions

View File

@@ -8793,8 +8793,15 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
ins2(c, A_LEAQ, amem(D_BP, soff),
areg(D_SI));
havesrc = 1;
/* the laid-out-aggregate globals (#129
* A.2/A.3): a let, an array def, or a struct
* def. Struct defs copy here exactly as
* struct-let globals do; omitting def_is-
* structdef truncated the def case alone and
* diverged from wwstage (rule-10). */
} else if (let_islet(n->rhs->str)
|| def_isarraydef(n->rhs->str)) {
|| def_isarraydef(n->rhs->str)
|| def_isstructdef(n->rhs->str)) {
ins2(c, A_LEAQ, masym(c, n->rhs->str),
areg(D_SI));
havesrc = 1;