cgen: peel *fn field types for local struct-field callees
fnptrcalleetfn's N_DOT arm accepted only a bare N_TFN field tnode, so a call through a field declared `cb: *fn(...)` missed, fell through to the name registry, and emitted CALL cb(SB) — an undefined symbol (loud at link; cstage calls the stamped ptr-to-fn indirectly). Same TPTR peel the N_IDENT arm already had. Fixture fnptrfield_call covers the by-value and via-pointer shapes; corpus pin 1478/2956.
This commit is contained in:
@@ -108,6 +108,18 @@ fn fnptrcalleetfn(c: *cgen, callee: *syntax.node) *syntax.node = {
|
||||
let ft: *syntax.node = fi.tnode;
|
||||
if (ft != nil) {
|
||||
if (ft.kind == syntax.nkind.N_TFN) { return ft; };
|
||||
// `cb: *fn(...)` — same TPTR peel as the N_IDENT
|
||||
// arm above; without it the field-call fell through
|
||||
// to the name registry and emitted CALL <leaf>(SB)
|
||||
// (undefined symbol — loud at link, but cstage
|
||||
// resolves the stamped ptr-to-fn and calls indirect).
|
||||
if (ft.kind == syntax.nkind.N_TPTR) {
|
||||
if (ft.lhs != nil) {
|
||||
if (ft.lhs.kind == syntax.nkind.N_TFN) {
|
||||
return ft.lhs;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user