w6c: sret-wire the chained-leaf call store (o.a.b = wide())
The chained value-struct walker's N_CALL arm handled only <=24B register returns; an sret-class rhs fell to the scalar tail and stored ONE word (the sret dest pointer) into the leaf -- silent truncation in BOTH stages, byteid-blind. Point the callee's hidden RDI at the BP-relative leaf slot (the single-dot #234 arm verbatim); a ptr-root/global chain joins the #234-tail loud-stop family.
This commit is contained in:
@@ -6768,6 +6768,29 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* #234: over-cap sret STORE into a chained
|
||||
* value-struct leaf — `o.a.b = wide();`
|
||||
* (cg_sret_retsize > 0: a >24B struct OR an
|
||||
* over-cap tuple). Point the callee's hidden
|
||||
* RDI dest at the leaf slot so it writes the
|
||||
* WHOLE value there; pre-#234 this fell to
|
||||
* the scalar tail and stored ONE word (the
|
||||
* sret dest pointer). cg_sret_dest_off is
|
||||
* BP-relative ONLY, so a ptr-root/global
|
||||
* chain needs the runtime RDI-pointer dest
|
||||
* variant deferred to #234-tail and HARD-
|
||||
* STOPS loud (rule 7). */
|
||||
if (n->rhs && n->rhs->kind == N_CALL
|
||||
&& cg_sret_retsize(leaf_type) > 0) {
|
||||
if (via_cx)
|
||||
fatal("#234-tail: over-cap tuple "
|
||||
"sret store to chained "
|
||||
"ptr/global dest unsupported");
|
||||
cg_sret_dest_off = base_disp + total_off;
|
||||
cgexpr(c, n->rhs, locals);
|
||||
cg_sret_dest_off = 0;
|
||||
break;
|
||||
}
|
||||
/* TY_STRUCT terminal in the chained-DOT walker:
|
||||
* three rhs shapes — mirror of the single-dot
|
||||
* branch.
|
||||
|
||||
Reference in New Issue
Block a user