ww: classify imported call returns canonically

This commit is contained in:
2026-08-14 11:14:52 +09:00
parent 10e02a00ee
commit 72e890d5aa
2 changed files with 22 additions and 11 deletions

View File

@@ -2492,13 +2492,20 @@ fn sretretsizetn(c: *cgen, t: *syntax.tinfo) i32 = {
return 0;
};
// callsretsize — if N_CALL `n`'s callee returns a plain TY_STRUCT
// > 24B, return its natural size; else 0. Wraps sretretsize over the
// callee's resolved return type, used by cglet / cgassign receive
// sites and cgcall to detect sret at the receive / emit boundaries.
// callsretsize — classify an N_CALL from the checker-stamped result type.
// The callee's return AST can belong to an imported interface source whose
// private canonical qualifier is deliberately invisible in the caller's file
// scope. Re-resolving that spelling here loses the canonical type and can
// select the wrong return ABI. Cstage classifies the checked Type directly;
// sretretsizetn is its isomorphic tinfo path.
fn callsretsize(c: *cgen, n: *syntax.node) i32 = {
if (n == nil) { return 0; };
if (n.kind != syntax.nkind.N_CALL) { return 0; };
if (n.type_ != nil) {
return sretretsizetn(c, n.type_: *syntax.tinfo);
};
// Raw cgen-only callers may supply an unchecked AST. Retain their
// historical name-based fallback; production checked calls never take it.
let callee: *syntax.node = n.lhs;
if (callee == nil) { return 0; };
let cn: str;
@@ -2519,10 +2526,8 @@ fn callsretsize(c: *cgen, n: *syntax.node) i32 = {
};
if (cn.len == 0) { return 0; };
let rtyp: *syntax.node = fnretlookupmod(c, cn, cmod);
// #129: sretretsize must see the CALLEE's module context so
// aliassamemod resolves aliases from the callee's module (not the
// caller's). Mirrors cstage operating on resolved Type* objects
// (type_chase_named never has this confusion). Swap + restore.
// The unchecked fallback still needs the callee module for its
// same-module alias preference; checked production calls bypass it above.
let savedmod: str = c.curmod;
if (cmod.len > 0) { c.curmod = cmod; };
let r: i32 = sretretsize(c, rtyp);