wcc/ww: &fn synthesis prefers the current module's fn
The address-of-fn synthesis used a bare lookup — import order could bind a same-leaf fn from another module, silently LEAQ-ing the wrong function into a fn-ptr slot. Prefer the current module (mirror check.c:410/1305). Report item #4 (loud and silent faces pinned).
This commit is contained in:
@@ -13130,7 +13130,12 @@ fn unoptype(c: *checker, e: *node) *node = {
|
||||
// (cmd/wcc/check.c:668), so `&fn` is `*fn` natively.
|
||||
if (e.lhs != nil) {
|
||||
if (e.lhs.kind == nkind.N_IDENT) {
|
||||
let fs: *sym = scopelookup(c.cur, e.lhs.str);
|
||||
// #4: curmod preference. A bare `&handler` whose leaf
|
||||
// also names a fn in a LATER module otherwise binds
|
||||
// the foreign signature (scopedefineinmodule prepends);
|
||||
// cstage types a fn ident via scope_lookup_prefer with
|
||||
// cur_mod (cmd/wcc/check.c:1305).
|
||||
let fs: *sym = scopelookupprefer(c.cur, c.curmod, e.lhs.str);
|
||||
if (fs != nil) {
|
||||
if (fs.skind == skind.SK_FN) {
|
||||
if (fs.decl != nil) {
|
||||
@@ -14635,7 +14640,13 @@ fn assignableaddrfn(c: *checker, dst: *node, rhs: *node) bool = {
|
||||
let id: *node = rhs.lhs;
|
||||
if (id == nil) { return false; };
|
||||
if (id.kind != nkind.N_IDENT) { return false; };
|
||||
let s: *sym = scopelookup(c.cur, id.str);
|
||||
// #4: curmod preference. Without it a `&handler` whose leaf also
|
||||
// names a fn in a later module misbinds the foreign fn's signature
|
||||
// here (scopedefineinmodule prepends → chain-first = last module),
|
||||
// silently admitting a *fn into a foreign-sig slot or rejecting a
|
||||
// valid same-module &fn. cstage uses scope_lookup_prefer with
|
||||
// cur_mod (cmd/wcc/check.c:410, assignable_addrfn).
|
||||
let s: *sym = scopelookupprefer(c.cur, c.curmod, id.str);
|
||||
if (s == nil) { return false; };
|
||||
if (s.skind != skind.SK_FN) { return false; };
|
||||
if (s.decl == nil) { return false; };
|
||||
|
||||
Reference in New Issue
Block a user