]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix loop depth of range expression in escape analysis
authorCherry Zhang <cherryyz@google.com>
Wed, 29 Nov 2017 20:55:40 +0000 (15:55 -0500)
committerCherry Zhang <cherryyz@google.com>
Thu, 30 Nov 2017 13:45:18 +0000 (13:45 +0000)
ORANGE node's Right node is the expression it is ranging over,
which is evaluated before the loop. In the escape analysis,
we should walk this node without loop depth incremented.

Fixes #21709.

Change-Id: Idc1e4c76e39afb5a344d85f6b497930a488ce5cf
Reviewed-on: https://go-review.googlesource.com/80740
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/gc/esc.go
test/fixedbugs/issue21709.go [new file with mode: 0644]

index 7ef07961deadb07a1fef497d81096d8917e6259e..03c0adafd5148ddfd5ad2b4e089f9d21d21bbd19 100644 (file)
@@ -680,7 +680,18 @@ func (e *EscState) esc(n *Node, parent *Node) {
        }
 
        e.esc(n.Left, n)
+
+       if n.Op == ORANGE {
+               // ORANGE node's Right is evaluated before the loop
+               e.loopdepth--
+       }
+
        e.esc(n.Right, n)
+
+       if n.Op == ORANGE {
+               e.loopdepth++
+       }
+
        e.esclist(n.Nbody, n)
        e.esclist(n.List, n)
        e.esclist(n.Rlist, n)
diff --git a/test/fixedbugs/issue21709.go b/test/fixedbugs/issue21709.go
new file mode 100644 (file)
index 0000000..bf5d9d2
--- /dev/null
@@ -0,0 +1,37 @@
+// errorcheck -0 -l -m
+
+// Copyright 2017 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.
+
+// Issue 21709: range expression overly escapes.
+
+package p
+
+type S struct{}
+
+func (s *S) Inc() {} // ERROR "\(\*S\).Inc s does not escape"
+var N int
+
+func F1() {
+       var s S // ERROR "moved to heap: s"
+       for i := 0; i < N; i++ {
+               fs := []func(){ // ERROR "F1 \[\]func\(\) literal does not escape"
+                       s.Inc, // ERROR "F1 s.Inc does not escape" "s escapes to heap"
+               }
+               for _, f := range fs {
+                       f()
+               }
+       }
+}
+
+func F2() {
+       var s S // ERROR "moved to heap: s"
+       for i := 0; i < N; i++ {
+               for _, f := range []func(){ // ERROR "F2 \[\]func\(\) literal does not escape"
+                       s.Inc, // ERROR "F2 s.Inc does not escape" "s escapes to heap"
+               } {
+                       f()
+               }
+       }
+}