]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: fix escape analysis problem with closures
authorDan Scales <danscales@google.com>
Sat, 23 Jan 2021 00:07:00 +0000 (16:07 -0800)
committerDan Scales <danscales@google.com>
Sat, 23 Jan 2021 02:15:24 +0000 (02:15 +0000)
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 <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/escape/escape.go
test/closure6.go [new file with mode: 0644]

index 883e68a730c1c3fc5dbf78f637a804590427bad4..58cad73c76230082e931d41bcdaf4e52b06051b3 100644 (file)
@@ -781,6 +781,16 @@ func (e *escape) exprSkipInit(k hole, n ir.Node) {
                                }
                        }
 
+                       for _, n := range fn.Dcl {
+                               // Add locations for local variables of the
+                               // closure, if needed, in case we're not including
+                               // the closure func in the batch for escape
+                               // analysis (happens for escape analysis called
+                               // from reflectdata.methodWrapper)
+                               if n.Op() == ir.ONAME && n.Opt == nil {
+                                       e.with(fn).newLoc(n, false)
+                               }
+                       }
                        e.walkFunc(fn)
                }
 
diff --git a/test/closure6.go b/test/closure6.go
new file mode 100644 (file)
index 0000000..b5592ad
--- /dev/null
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Float64Slice []float64
+
+func (a Float64Slice) Search1(x float64) int {
+       f := func(q int) bool { return a[q] >= x }
+       i := 0
+       if !f(3) {
+               i = 5
+       }
+       return i
+}