diff --git a/src/cmd/compile/internal/gc/pgen.go b/src/cmd/compile/internal/gc/pgen.go index 6ccd0b8d94..74654c86bc 100644 --- a/src/cmd/compile/internal/gc/pgen.go +++ b/src/cmd/compile/internal/gc/pgen.go @@ -271,7 +271,7 @@ func compile(fn *Node) { } } - if compilenow() { + if compilenow(fn) { compileSSA(fn, 0) } else { compilequeue = append(compilequeue, fn) @@ -282,10 +282,31 @@ func compile(fn *Node) { // If functions are not compiled immediately, // they are enqueued in compilequeue, // which is drained by compileFunctions. -func compilenow() bool { +func compilenow(fn *Node) bool { + // Issue 38068: if this function is a method AND an inline + // candidate AND was not inlined (yet), put it onto the compile + // queue instead of compiling it immediately. This is in case we + // wind up inlining it into a method wrapper that is generated by + // compiling a function later on in the xtop list. + if fn.IsMethod() && isInlinableButNotInlined(fn) { + return false + } return nBackendWorkers == 1 && Debug_compilelater == 0 } +// isInlinableButNotInlined returns true if 'fn' was marked as an +// inline candidate but then never inlined (presumably because we +// found no call sites). +func isInlinableButNotInlined(fn *Node) bool { + if fn.Func.Nname.Func.Inl == nil { + return false + } + if fn.Sym == nil { + return true + } + return !fn.Sym.Linksym().WasInlined() +} + const maxStackSize = 1 << 30 // compileSSA builds an SSA backend function, diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index 6d7f42ed0b..93c313862e 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -788,6 +788,14 @@ func (ft *DwarfFixupTable) SetPrecursorFunc(s *LSym, fn interface{}) { absfn.Type = objabi.SDWARFINFO ft.ctxt.Data = append(ft.ctxt.Data, absfn) + // In the case of "late" inlining (inlines that happen during + // wrapper generation as opposed to the main inlining phase) it's + // possible that we didn't cache the abstract function sym for the + // text symbol -- do so now if needed. See issue 38068. + if s.Func != nil && s.Func.dwarfAbsFnSym == nil { + s.Func.dwarfAbsFnSym = absfn + } + ft.precursor[s] = fnState{precursor: fn, absfn: absfn} }