From: Daniel Morsing Date: Thu, 13 Feb 2014 19:04:43 +0000 (+0000) Subject: cmd/gc: for loop init statement misanalyzed by escape analysis X-Git-Tag: go1.3beta1~724 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=e0a55a6c9826f3b0548a2d78be82931ad73ac218;p=gostls13.git cmd/gc: for loop init statement misanalyzed by escape analysis Logically, the init statement is in the enclosing scopes loopdepth, not inside the for loop. Fixes #7313. LGTM=rsc R=golang-codereviews, gobot, rsc CC=golang-codereviews https://golang.org/cl/62430043 --- diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c index 99e4134a8c..c038dfc589 100644 --- a/src/cmd/gc/esc.c +++ b/src/cmd/gc/esc.c @@ -423,6 +423,9 @@ esc(EscState *e, Node *n) lno = setlineno(n); + // ninit logically runs at a different loopdepth than the rest of the for loop. + esclist(e, n->ninit); + if(n->op == OFOR || n->op == ORANGE) e->loopdepth++; @@ -430,7 +433,6 @@ esc(EscState *e, Node *n) esc(e, n->right); esc(e, n->ntest); esc(e, n->nincr); - esclist(e, n->ninit); esclist(e, n->nbody); esclist(e, n->nelse); esclist(e, n->list); diff --git a/test/escape2.go b/test/escape2.go index be89c2d840..73342fd2bc 100644 --- a/test/escape2.go +++ b/test/escape2.go @@ -1357,3 +1357,35 @@ func foo144() { //go:noescape func foo144b(*int) + +// issue 7313: for loop init should not be treated as "in loop" + +type List struct { + Next *List +} + +func foo145(l List) { // ERROR "l does not escape" + var p *List + for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape" + } +} + +func foo146(l List) { // ERROR "l does not escape" + var p *List + p = &l // ERROR "&l does not escape" + for ; p.Next != nil; p = p.Next { + } +} + +func foo147(l List) { // ERROR "l does not escape" + var p *List + p = &l // ERROR "&l does not escape" + for p.Next != nil { + p = p.Next + } +} + +func foo148(l List) { // ERROR " l does not escape" + for p := &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape" + } +}