mirror of https://github.com/golang/go.git
cmd/gc: fix escape analysis bug with variable capture in loops.
Fixes #3975. R=rsc, lvd CC=golang-dev, remy https://golang.org/cl/6475061
This commit is contained in:
parent
3efc482190
commit
ba97d52b85
|
|
@ -543,6 +543,7 @@ esc(EscState *e, Node *n)
|
||||||
continue;
|
continue;
|
||||||
a = nod(OADDR, ll->n->closure, N);
|
a = nod(OADDR, ll->n->closure, N);
|
||||||
a->lineno = ll->n->lineno;
|
a->lineno = ll->n->lineno;
|
||||||
|
a->escloopdepth = e->loopdepth;
|
||||||
typecheck(&a, Erv);
|
typecheck(&a, Erv);
|
||||||
escassign(e, n, a);
|
escassign(e, n, a);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,15 +18,15 @@ var allptr = make([]*int, 0, 100)
|
||||||
|
|
||||||
func noalias(p, q *int, s string) {
|
func noalias(p, q *int, s string) {
|
||||||
n := len(allptr)
|
n := len(allptr)
|
||||||
*p = -(n+1)
|
*p = -(n + 1)
|
||||||
*q = -(n+2)
|
*q = -(n + 2)
|
||||||
allptr = allptr[0:n+2]
|
allptr = allptr[0 : n+2]
|
||||||
allptr[n] = p
|
allptr[n] = p
|
||||||
allptr[n+1] = q
|
allptr[n+1] = q
|
||||||
n += 2
|
n += 2
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
if allptr[i] != nil && *allptr[i] != -(i+1) {
|
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
|
allptr[i] = nil
|
||||||
bad = true
|
bad = true
|
||||||
}
|
}
|
||||||
|
|
@ -141,6 +141,18 @@ func for_escapes2(x int, y int) (*int, *int) {
|
||||||
return p[0], p[1]
|
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) {
|
func out_escapes(i int) (x int, p *int) {
|
||||||
x = i
|
x = i
|
||||||
p = &x // ERROR "address of out parameter"
|
p = &x // ERROR "address of out parameter"
|
||||||
|
|
@ -187,6 +199,9 @@ func main() {
|
||||||
p, q = for_escapes2(103, 104)
|
p, q = for_escapes2(103, 104)
|
||||||
chkalias(p, q, 103, "for_escapes2")
|
chkalias(p, q, 103, "for_escapes2")
|
||||||
|
|
||||||
|
p, q = for_escapes3(105, 106)
|
||||||
|
chk(p, q, 105, "for_escapes3")
|
||||||
|
|
||||||
_, p = out_escapes(15)
|
_, p = out_escapes(15)
|
||||||
_, q = out_escapes(16)
|
_, q = out_escapes(16)
|
||||||
chk(p, q, 15, "out_escapes")
|
chk(p, q, 15, "out_escapes")
|
||||||
|
|
|
||||||
|
|
@ -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"
|
func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y"
|
||||||
return y
|
return y
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue