Skip to content

Commit

Permalink
cmd/compile: fix loop depth of range expression in escape analysis
Browse files Browse the repository at this point in the history
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 <[email protected]>
TryBot-Result: Gobot Gobot <[email protected]>
Reviewed-by: David Chase <[email protected]>
  • Loading branch information
cherrymui committed Nov 30, 2017
1 parent 8064f82 commit dbb1d19
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/cmd/compile/internal/gc/esc.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
37 changes: 37 additions & 0 deletions test/fixedbugs/issue21709.go
Original file line number Diff line number Diff line change
@@ -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()
}
}
}

0 comments on commit dbb1d19

Please sign in to comment.