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.
23 lines
510 B
Plaintext
23 lines
510 B
Plaintext
//ww:run-exit 36
|
|
package main;
|
|
|
|
// A call through a struct field declared `*fn(...)`, by value and via
|
|
// pointer. The wwstage fnptrcalleetfn N_DOT arm lacked the TPTR peel
|
|
// its N_IDENT arm had, so the callee fell through to the name registry
|
|
// and emitted CALL cb(SB) — an undefined symbol.
|
|
|
|
type cbs = struct {
|
|
cb: *fn(x: i32) i32,
|
|
k: i32,
|
|
};
|
|
|
|
fn twice(x: i32) i32 = { return x * 2; };
|
|
|
|
fn main() i32 = {
|
|
let o: cbs;
|
|
o.cb = &twice;
|
|
o.k = 4;
|
|
let p: *cbs = &o;
|
|
return o.cb(10) + p.cb(6) + o.k;
|
|
};
|