diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/inline/inl.go | 2 | ||||
| -rw-r--r-- | src/cmd/compile/internal/ir/func.go | 18 | ||||
| -rw-r--r-- | src/cmd/internal/obj/inl.go | 32 |
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) { |
