diff options
author | Andrew Gerrand <adg@golang.org> | 2012-09-22 05:54:55 +1000 |
---|---|---|
committer | Andrew Gerrand <adg@golang.org> | 2012-09-22 05:54:55 +1000 |
commit | dfd413bda12d684c03eb1ac7a3451da10e24dabd (patch) | |
tree | 4194ac64427290704fdb9e493441889cd8e234dc | |
parent | 7ed136f1215c97f74936e3d53c2360f1b11ce377 (diff) | |
download | go-dfd413bda12d684c03eb1ac7a3451da10e24dabd.tar.gz go-dfd413bda12d684c03eb1ac7a3451da10e24dabd.zip |
[release-branch.go1] cmd/gc: fix escape analysis bug with variable capture in loops.
-rw-r--r-- | src/cmd/gc/esc.c | 3 | ||||
-rw-r--r-- | test/escape.go | 27 | ||||
-rw-r--r-- | test/escape2.go | 13 |
3 files changed, 37 insertions, 6 deletions
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c index 8a265ce59a..e0ba31fd63 100644 --- a/src/cmd/gc/esc.c +++ b/src/cmd/gc/esc.c @@ -143,6 +143,9 @@ escfunc(Node *func) n = nod(OADDR, ll->n->closure, N); n->lineno = ll->n->lineno; + // n belongs to the outer scope. + n->escloopdepth = saveld; + n->curfn = savefn; typecheck(&n, Erv); escassign(curfn, n); } diff --git a/test/escape.go b/test/escape.go index e487bb8956..e8ede52760 100644 --- a/test/escape.go +++ b/test/escape.go @@ -18,15 +18,15 @@ var allptr = make([]*int, 0, 100) func noalias(p, q *int, s string) { n := len(allptr) - *p = -(n+1) - *q = -(n+2) - allptr = allptr[0:n+2] + *p = -(n + 1) + *q = -(n + 2) + allptr = allptr[0 : n+2] allptr[n] = p allptr[n+1] = q n += 2 for i := 0; i < n; i++ { if allptr[i] != nil && *allptr[i] != -(i+1) { - println("aliased pointers", -(i+1), *allptr[i], "after", s) + println("aliased pointers", -(i + 1), *allptr[i], "after", s) allptr[i] = nil bad = true } @@ -141,15 +141,27 @@ func for_escapes2(x int, y int) (*int, *int) { return p[0], p[1] } +func for_escapes3(x int, y int) (*int, *int) { + var f [2]func() *int + n := 0 + for i := x; n < 2; i = y { + p := new(int) + *p = i + f[n] = func() *int { return p } + n++ + } + return f[0](), f[1]() +} + func out_escapes(i int) (x int, p *int) { x = i - p = &x // ERROR "address of out parameter" + p = &x // ERROR "address of out parameter" return } func out_escapes_2(i int) (x int, p *int) { x = i - return x, &x // ERROR "address of out parameter" + return x, &x // ERROR "address of out parameter" } func defer1(i int) (x int) { @@ -187,6 +199,9 @@ func main() { p, q = for_escapes2(103, 104) chkalias(p, q, 103, "for_escapes2") + p, q = for_escapes3(105, 106) + chk(p, q, 105, "for_escapes3") + _, p = out_escapes(15) _, q = out_escapes(16) chk(p, q, 15, "out_escapes") diff --git a/test/escape2.go b/test/escape2.go index 0bf02c5342..462caee9fc 100644 --- a/test/escape2.go +++ b/test/escape2.go @@ -540,6 +540,19 @@ func foo74() { } } +// issue 3975 +func foo74b() { + var array [3]func() + s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" + for i, v := range s { + vv := v // ERROR "moved to heap: vv" + // actually just escapes its scope + array[i] = func() { // ERROR "func literal escapes to heap" + println(vv) // ERROR "&vv escapes to heap" + } + } +} + func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y" return y } |