wwstage: classify tagged call-source by stamped result type, not callee leaf name (#211)
rhstaggedabicall keyed the tagged-vs-scalar call-source decision off the callee result type looked up by leaf NAME (fnretlookupmod), with the receiver variable used as the "module". A value-receiver fn-ptr field call s.f(...) whose leaf collides with a same-named global fn then mis-bound the global's register shape, so the source was misclassified as scalar and widened wrong: silent cs/ww asm divergence and wrong runtime. Read the checker-stamped N_CALL result type (src.type_) instead, mirroring the N_DOT sister branch. cstage already reads u->ret off the typed callee (cmd/wcc/check.c:1490) and harec selects by interned type id, not name (ref/harec/src/types.c:714). Graduates test/wcc/782 to STAGE_WW + byte_id.
This commit is contained in:
@@ -2514,31 +2514,17 @@ fn rhstaggedident(c: *cgen, src: *node) *node = {
|
||||
fn rhstaggedabicall(c: *cgen, src: *node) bool = {
|
||||
if (src == nil) { return false; };
|
||||
if (src.kind == nkind.N_CALL) {
|
||||
let callee: *node = src.lhs;
|
||||
if (callee != nil) {
|
||||
let calleename: str;
|
||||
calleename.ptr = nil; calleename.len = 0;
|
||||
let cmod: str;
|
||||
cmod.ptr = nil; cmod.len = 0;
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
calleename = callee.str;
|
||||
cmod = c.curmod;
|
||||
};
|
||||
if (callee.kind == nkind.N_DOT) {
|
||||
calleename = callee.str;
|
||||
if (callee.lhs != nil) {
|
||||
if (callee.lhs.kind == nkind.N_IDENT) {
|
||||
cmod = callee.lhs.str;
|
||||
};
|
||||
};
|
||||
};
|
||||
if (calleename.len > 0) {
|
||||
let rtyp: *node = fnretlookupmod(c, calleename, cmod);
|
||||
if (rtyp != nil) {
|
||||
if (istaggedtype(c, rtyp)) { return true; };
|
||||
};
|
||||
};
|
||||
};
|
||||
// #211: a call's result type is the CALLEE's fn-type ret, which
|
||||
// the checker stamps onto this N_CALL node (check.ww N_CALL: both
|
||||
// the SK_FN path and the fn-VALUE/field path set e.type_ = the
|
||||
// result tinfo). Read it directly — a value-receiver fn-ptr FIELD
|
||||
// call `s.f(...)` keyed by the field leaf `f` with the receiver
|
||||
// VARIABLE name as the "module" otherwise mis-binds a same-named
|
||||
// GLOBAL fn of different register shape (silent cs≠ww). cstage's
|
||||
// sister reads u->ret off the callee type (cmd/wcc/check.c:1433,
|
||||
// :1490); harec selects by interned type id, not name (ref/harec/
|
||||
// src/types.c:714). Mirrors the N_DOT branch below.
|
||||
if (typeistagged(src.type_: *tinfo)) { return true; };
|
||||
return false;
|
||||
};
|
||||
if (src.kind == nkind.N_INDEX) {
|
||||
|
||||
Reference in New Issue
Block a user