cgen: accept an indexed source in aggregate element assignment

The a[i] = src copy loop enumerated ident/field/deref sources; an
N_INDEX rhs fell to the scalar tail and truncated the element. Route
it through the generic place-address funnel. Both stages.
This commit is contained in:
2026-08-07 23:00:02 +09:00
parent 078708770b
commit 7dc3150b65
3 changed files with 47 additions and 8 deletions

View File

@@ -7295,8 +7295,9 @@ cgexpr(Cg *c, Node *n, Local *locals)
* address, then word-copy esz bytes: the WRITE-twin of the
* #268 let-init copy loop. Source shapes mirror that loop
* (ident local/global, N_DOT field via cg_dotchain_addr,
* `*p` deref); struct-lit sources divert at the place_slit
* gate above (#20), array-lit dies loud (task #32), and a
* N_INDEX via cgplaceaddr, `*p` deref); struct-lit sources
* divert at the place_slit gate above (#20), array-lit dies
* loud (task #32), and a
* by-value call result still falls to the scalar tail —
* RAX-only store, task #31-G. */
if ((is_arr || is_sl || is_ptr) && n->op == TK_ASSIGN
@@ -7306,6 +7307,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
&& esz > 8
&& ((n->rhs->kind == N_IDENT)
|| (n->rhs->kind == N_DOT)
|| (n->rhs->kind == N_INDEX)
|| (n->rhs->kind == N_UN
&& n->rhs->op == TK_STAR))) {
/* dest &a[i] → BX */
@@ -7358,8 +7360,11 @@ cgexpr(Cg *c, Node *n, Local *locals)
ins2(c, A_LEAQ,
masym(c, n->rhs->str),
areg(D_SI));
} else {
} else if (n->rhs->kind == N_DOT) {
cg_dotchain_addr(c, n->rhs, D_SI, locals);
} else if (!cgplaceaddr(c, n->rhs, D_SI, locals)) {
fatal("indexed aggregate assignment source "
"unresolved");
}
ins1(c, A_POPQ, areg(D_BX)); /* dest */
int k = 0;