]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/gc: fix escape analysis bug with variable capture in loops.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Fri, 31 Aug 2012 20:23:37 +0000 (22:23 +0200)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Fri, 31 Aug 2012 20:23:37 +0000 (22:23 +0200)
Fixes #3975.

R=rsc, lvd
CC=golang-dev, remy
https://golang.org/cl/6475061

src/cmd/gc/esc.c
test/escape.go
test/escape2.go

index 971e430f7913a9bec1fe25155b4141e41b5db43c..282be9a5d4a71dbbabc44a0f24b018fc43e8b796 100644 (file)
@@ -543,6 +543,7 @@ esc(EscState *e, Node *n)
                                continue;
                        a = nod(OADDR, ll->n->closure, N);
                        a->lineno = ll->n->lineno;
+                       a->escloopdepth = e->loopdepth;
                        typecheck(&a, Erv);
                        escassign(e, n, a);
                }
index e487bb89565f3fd75af9229e1843b810b9f043d5..e8ede52760aa4b6418b3585a0278ce1d27142f02 100644 (file)
@@ -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")
index 0bf02c5342c744937a7d11a78e976902109e5488..462caee9fc2eed836ec9df0c0628eaf6d1e5c962 100644 (file)
@@ -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
 }