Skip to content

Commit

Permalink
cmd/gc: for loop init statement misanalyzed by escape analysis
Browse files Browse the repository at this point in the history
Logically, the init statement is in the enclosing scopes loopdepth, not inside the for loop.

Fixes golang#7313.

LGTM=rsc
R=golang-codereviews, gobot, rsc
CC=golang-codereviews
https://golang.org/cl/62430043
  • Loading branch information
DanielMorsing committed Feb 13, 2014
1 parent 7861cd6 commit e0a55a6
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/cmd/gc/esc.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,14 +423,16 @@ 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++;

esc(e, n->left);
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);
Expand Down
32 changes: 32 additions & 0 deletions test/escape2.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}

0 comments on commit e0a55a6

Please sign in to comment.