Skip to content

Commit 48badc5

Browse files
committed
[dev.regabi] cmd/compile: fix escape analysis problem with closures
In reflect.methodWrapper, we call escape analysis without including the full batch of dependent functions, including the closure functions. Because of this, we haven't created locations for the params/local variables of a closure when we are processing a function that inlines that closure. (Whereas in the normal compilation of the function, we do call with the full batch.) To deal with this, I am creating locations for the params/local variables of a closure when needed. Without this fix, the new test closure6.go would fail. Updates #43818 Change-Id: I5f91cfb6f35efe2937ef88cbcc468e403e0da9ad Reviewed-on: https://go-review.googlesource.com/c/go/+/285677 Run-TryBot: Dan Scales <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Dan Scales <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 51e1819 commit 48badc5

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

src/cmd/compile/internal/escape/escape.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,16 @@ func (e *escape) exprSkipInit(k hole, n ir.Node) {
781781
}
782782
}
783783

784+
for _, n := range fn.Dcl {
785+
// Add locations for local variables of the
786+
// closure, if needed, in case we're not including
787+
// the closure func in the batch for escape
788+
// analysis (happens for escape analysis called
789+
// from reflectdata.methodWrapper)
790+
if n.Op() == ir.ONAME && n.Opt == nil {
791+
e.with(fn).newLoc(n, false)
792+
}
793+
}
784794
e.walkFunc(fn)
785795
}
786796

test/closure6.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// compile
2+
3+
// Copyright 2020 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package p
8+
9+
type Float64Slice []float64
10+
11+
func (a Float64Slice) Search1(x float64) int {
12+
f := func(q int) bool { return a[q] >= x }
13+
i := 0
14+
if !f(3) {
15+
i = 5
16+
}
17+
return i
18+
}

0 commit comments

Comments
 (0)