cmd/compile: move FuncPC intrinsic handling to common helper

CL 539699 will need to do the equivalent of
internal/abi.FuncPCABIInternal to get the PC of a function value for the
runtime devirtualization check.

Move the FuncPC expression creation from the depths of walk to a
typecheck helper so it can be reused in both places.

For #61577.

Change-Id: I76f333157cf0e5fd867b41bfffcdaf6f45254707
Reviewed-on: https://go-review.googlesource.com/c/go/+/539698
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Michael Pratt 2023-11-03 16:00:40 -04:00 committed by Gopher Robot
parent 505dff4fe2
commit e323e7d973
3 changed files with 60 additions and 29 deletions

View file

@ -559,30 +559,11 @@ func walkCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
case "FuncPCABIInternal":
wantABI = obj.ABIInternal
}
if isIfaceOfFunc(arg) {
fn := arg.(*ir.ConvExpr).X.(*ir.Name)
abi := fn.Func.ABI
if abi != wantABI {
base.ErrorfAt(n.Pos(), 0, "internal/abi.%s expects an %v function, %s is defined as %v", name, wantABI, fn.Sym().Name, abi)
}
var e ir.Node = ir.NewLinksymExpr(n.Pos(), fn.Sym().LinksymABI(abi), types.Types[types.TUINTPTR])
e = ir.NewAddrExpr(n.Pos(), e)
e.SetType(types.Types[types.TUINTPTR].PtrTo())
return typecheck.Expr(ir.NewConvExpr(n.Pos(), ir.OCONVNOP, n.Type(), e))
if n.Type() != types.Types[types.TUINTPTR] {
base.FatalfAt(n.Pos(), "FuncPC intrinsic should return uintptr, got %v", n.Type()) // as expected by typecheck.FuncPC.
}
// fn is not a defined function. It must be ABIInternal.
// Read the address from func value, i.e. *(*uintptr)(idata(fn)).
if wantABI != obj.ABIInternal {
base.ErrorfAt(n.Pos(), 0, "internal/abi.%s does not accept func expression, which is ABIInternal", name)
}
arg = walkExpr(arg, init)
var e ir.Node = ir.NewUnaryExpr(n.Pos(), ir.OIDATA, arg)
e.SetType(n.Type().PtrTo())
e.SetTypecheck(1)
e = ir.NewStarExpr(n.Pos(), e)
e.SetType(n.Type())
e.SetTypecheck(1)
return e
n := ir.FuncPC(n.Pos(), arg, wantABI)
return walkExpr(n, init)
}
if name, ok := n.Fun.(*ir.Name); ok {