package main
-// check for correct heap-moving of escaped variables.
-// it is hard to check for the allocations, but it is easy
+// Test for correct heap-moving of escaped variables.
+// It is hard to check for the allocations, but it is easy
// to check that if you call the function twice at the
// same stack level, the pointers returned should be
// different.
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
}
func chkalias(p, q *int, v int, s string) {
if p != q {
println("want aliased pointers but got different after", s)
+ bad = true
}
if *q != v+1 {
println("wrong value want", v+1, "got", *q, "after", s)
+ bad = true
}
}
var p [2]*int
a[0] = x
a[1] = y
- for k, v := range a {
+ var k, v int
+ for k, v = range a {
p[k] = &v
}
return p[0], p[1]
func for_escapes2(x int, y int) (*int, *int) {
var p [2]*int
n := 0
- for i := x; n < 2; i = y {
+ i := x
+ for ; n < 2; i = y {
p[n] = &i
n++
}
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) {
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")