aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/inline/inl.go2
-rw-r--r--src/cmd/compile/internal/ir/func.go18
-rw-r--r--src/cmd/internal/obj/inl.go32
3 files changed, 37 insertions, 15 deletions
diff --git a/src/cmd/compile/internal/inline/inl.go b/src/cmd/compile/internal/inline/inl.go
index 96a6f3028a..c61d6d2234 100644
--- a/src/cmd/compile/internal/inline/inl.go
+++ b/src/cmd/compile/internal/inline/inl.go
@@ -1094,7 +1094,7 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, bigCaller bool, inlCalls *[]*ir.Inli
typecheck.AssertFixedCall(n)
- inlIndex := base.Ctxt.InlTree.Add(parent, n.Pos(), sym)
+ inlIndex := base.Ctxt.InlTree.Add(parent, n.Pos(), sym, ir.FuncName(fn))
closureInitLSym := func(n *ir.CallExpr, fn *ir.Func) {
// The linker needs FuncInfo metadata for all inlined
diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go
index b36b1fa494..5c41893fc6 100644
--- a/src/cmd/compile/internal/ir/func.go
+++ b/src/cmd/compile/internal/ir/func.go
@@ -11,6 +11,7 @@ import (
"cmd/internal/objabi"
"cmd/internal/src"
"fmt"
+ "strings"
)
// A Func corresponds to a single function in a Go program
@@ -359,8 +360,8 @@ func IsTrivialClosure(clo *ClosureExpr) bool {
// globClosgen is like Func.Closgen, but for the global scope.
var globClosgen int32
-// closureName generates a new unique name for a closure within outerfn.
-func closureName(outerfn *Func) *types.Sym {
+// closureName generates a new unique name for a closure within outerfn at pos.
+func closureName(outerfn *Func, pos src.XPos) *types.Sym {
pkg := types.LocalPkg
outer := "glob."
prefix := "func"
@@ -382,6 +383,17 @@ func closureName(outerfn *Func) *types.Sym {
}
}
+ // If this closure was created due to inlining, then incorporate any
+ // inlined functions' names into the closure's linker symbol name
+ // too (#60324).
+ if inlIndex := base.Ctxt.InnermostPos(pos).Base().InliningIndex(); inlIndex >= 0 {
+ names := []string{outer}
+ base.Ctxt.InlTree.AllParents(inlIndex, func(call obj.InlinedCall) {
+ names = append(names, call.Name)
+ })
+ outer = strings.Join(names, ".")
+ }
+
*gen++
return pkg.Lookup(fmt.Sprintf("%s.%s%d", outer, prefix, *gen))
}
@@ -418,7 +430,7 @@ func NameClosure(clo *ClosureExpr, outerfn *Func) {
base.FatalfAt(clo.Pos(), "closure already named: %v", name)
}
- name.SetSym(closureName(outerfn))
+ name.SetSym(closureName(outerfn, clo.Pos()))
MarkFunc(name)
}
diff --git a/src/cmd/internal/obj/inl.go b/src/cmd/internal/obj/inl.go
index 7a22eb1efd..6874471891 100644
--- a/src/cmd/internal/obj/inl.go
+++ b/src/cmd/internal/obj/inl.go
@@ -50,21 +50,37 @@ type InlinedCall struct {
Parent int // index of the parent in the InlTree or < 0 if outermost call
Pos src.XPos // position of the inlined call
Func *LSym // function that was inlined
+ Name string // bare name of the function (w/o package prefix)
ParentPC int32 // PC of instruction just before inlined body. Only valid in local trees.
}
// Add adds a new call to the tree, returning its index.
-func (tree *InlTree) Add(parent int, pos src.XPos, func_ *LSym) int {
+func (tree *InlTree) Add(parent int, pos src.XPos, func_ *LSym, name string) int {
r := len(tree.nodes)
call := InlinedCall{
Parent: parent,
Pos: pos,
Func: func_,
+ Name: name,
}
tree.nodes = append(tree.nodes, call)
return r
}
+// AllParents invokes do on each InlinedCall in the inlining call
+// stack, from outermost to innermost.
+//
+// That is, if inlIndex corresponds to f inlining g inlining h,
+// AllParents invokes do with the call for inlining g into f, and then
+// inlining h into g.
+func (tree *InlTree) AllParents(inlIndex int, do func(InlinedCall)) {
+ if inlIndex >= 0 {
+ call := tree.nodes[inlIndex]
+ tree.AllParents(call.Parent, do)
+ do(call)
+ }
+}
+
func (tree *InlTree) Parent(inlIndex int) int {
return tree.nodes[inlIndex].Parent
}
@@ -113,16 +129,10 @@ func (ctxt *Link) InnermostPos(xpos src.XPos) src.Pos {
// AllPos invokes do with the position in f, then the position in g, then the position in h.
func (ctxt *Link) AllPos(xpos src.XPos, do func(src.Pos)) {
pos := ctxt.InnermostPos(xpos)
- ctxt.forAllPos(pos.Base().InliningIndex(), do)
- do(ctxt.PosTable.Pos(xpos))
-}
-
-func (ctxt *Link) forAllPos(ix int, do func(src.Pos)) {
- if ix >= 0 {
- call := ctxt.InlTree.nodes[ix]
- ctxt.forAllPos(call.Parent, do)
- do(ctxt.PosTable.Pos(call.Pos))
- }
+ ctxt.InlTree.AllParents(pos.Base().InliningIndex(), func(call InlinedCall) {
+ do(ctxt.InnermostPos(call.Pos))
+ })
+ do(pos)
}
func dumpInlTree(ctxt *Link, tree InlTree) {