diff --git a/src/cmd/compile/internal/escape/escape.go b/src/cmd/compile/internal/escape/escape.go index c63383af43a..bee3878f100 100644 --- a/src/cmd/compile/internal/escape/escape.go +++ b/src/cmd/compile/internal/escape/escape.go @@ -126,6 +126,11 @@ type location struct { edges []edge // incoming edges loopDepth int // loopDepth at declaration + // resultIndex records the tuple index (starting at 1) for + // PPARAMOUT variables within their function's result type. + // For non-PPARAMOUT variables it's 0. + resultIndex int + // derefs and walkgen are used during walkOne to track the // minimal dereferences from the walk root. derefs int // >= -1 @@ -259,11 +264,16 @@ func (b *batch) initFunc(fn *ir.Func) { } // Allocate locations for local variables. - for _, dcl := range fn.Dcl { - if dcl.Op() == ir.ONAME { - e.newLoc(dcl, false) + for _, n := range fn.Dcl { + if n.Op() == ir.ONAME { + e.newLoc(n, false) } } + + // Initialize resultIndex for result parameters. + for i, f := range fn.Type().Results().FieldSlice() { + e.oldLoc(f.Nname.(*ir.Name)).resultIndex = 1 + i + } } func (b *batch) walkFunc(fn *ir.Func) { @@ -1609,8 +1619,7 @@ func (l *location) leakTo(sink *location, derefs int) { // If sink is a result parameter and we can fit return bits // into the escape analysis tag, then record a return leak. if sink.isName(ir.PPARAMOUT) && sink.curfn == l.curfn { - // TODO(mdempsky): Eliminate dependency on Vargen here. - ri := int(sink.n.Name().Vargen) - 1 + ri := sink.resultIndex - 1 if ri < numEscResults { // Leak to result parameter. l.paramEsc.AddResult(ri, derefs)