wcc/ww: nodefnptr keys the bare-ident arm on the stamped type
nodefnptr matched bare idents by NAME against the fn table, so a global var colliding with a fn leaf classified as a fn pointer — wwstage silently built what cstage rejects at link (review finding #14). Key on the stamped type; the #124 &mod.fn arm is preserved. 989_fnptrcollide_run pins both stages reject (red 1/2 pre-fix: wwstage built rc=7).
This commit is contained in:
@@ -42250,8 +42250,20 @@ fn nodefnptr(c: *cgen, ev: *node) bool = {
|
||||
return true;
|
||||
};
|
||||
if (opnd.kind != nkind.N_IDENT) { return false; };
|
||||
if (fnretlookup(c, opnd.str) == nil) { return false; };
|
||||
return true;
|
||||
// #14 (F7-c7): type-keyed, mirroring cstage node_fnptr_sym
|
||||
// (type_chase_named(opnd->type)->kind == TY_FN, cmd/w6c/cgen.c:15542-
|
||||
// 15543). The prior name-keyed `fnretlookup(opnd.str)` matched a fn
|
||||
// LEAF NAME even when the operand actually resolved to a same-named
|
||||
// global/local VALUE — so `&g` for an `*i64` global `g` colliding with
|
||||
// a fn `g` (e.g. a `mod.f` fn vs a `f` global) baked the fn's TEXT addr
|
||||
// into the scalar slot (ww runs rc=42; cs fails loud at w6l). Reading
|
||||
// the stamped operand type distinguishes the bare fn rvalue (TY_FN, the
|
||||
// #34 fn-rvalue stamp) from a value ident, closing the leaf-name
|
||||
// collision by construction. (F12 name-keyed overlap noted in the F7
|
||||
// spec — same predicate-to-stamp shape; fixed once here.)
|
||||
let ou: *tinfo = tichase(opnd.type_: *tinfo);
|
||||
if (ou == nil) { return false; };
|
||||
return ou.kind == tykind.TY_FN;
|
||||
};
|
||||
|
||||
// tuplerowfoldable — validate every cast-peeled element of `rhs` (an
|
||||
|
||||
Reference in New Issue
Block a user