aboutsummaryrefslogtreecommitdiff
path: root/test/escape2n.go
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2015-09-15 13:49:18 -0700
committerDan Willemsen <dwillemsen@google.com>2015-09-15 13:51:48 -0700
commit6ff23253f8283d0c81c9db51c2d7803e086c93ad (patch)
treed70b53746897f5f6a71c19b7c062a079b4f54001 /test/escape2n.go
parent1630e73131c3c8cc2a16baa2aefe3b9b82de658b (diff)
downloadlinux-x86-6ff23253f8283d0c81c9db51c2d7803e086c93ad.tar.gz
Change-Id: Ic39c72590cb0561132faefbca121c3782372b9bf
Diffstat (limited to 'test/escape2n.go')
-rw-r--r--test/escape2n.go1048
1 files changed, 692 insertions, 356 deletions
diff --git a/test/escape2n.go b/test/escape2n.go
index 002a78ea5..c32877321 100644
--- a/test/escape2n.go
+++ b/test/escape2n.go
@@ -18,94 +18,94 @@ import (
var gxx *int
-func foo1(x int) { // ERROR "moved to heap: x"
- gxx = &x // ERROR "&x escapes to heap"
+func foo1(x int) { // ERROR "moved to heap: x$"
+ gxx = &x // ERROR "&x escapes to heap$"
}
-func foo2(yy *int) { // ERROR "leaking param: yy"
+func foo2(yy *int) { // ERROR "leaking param: yy$"
gxx = yy
}
-func foo3(x int) *int { // ERROR "moved to heap: x"
- return &x // ERROR "&x escapes to heap"
+func foo3(x int) *int { // ERROR "moved to heap: x$"
+ return &x // ERROR "&x escapes to heap$"
}
type T *T
-func foo3b(t T) { // ERROR "leaking param: t"
+func foo3b(t T) { // ERROR "leaking param: t$"
*t = t
}
// xx isn't going anywhere, so use of yy is ok
-func foo4(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+func foo4(xx, yy *int) { // ERROR "foo4 xx does not escape$" "foo4 yy does not escape$"
xx = yy
}
// xx isn't going anywhere, so taking address of yy is ok
-func foo5(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
- xx = &yy // ERROR "&yy does not escape"
+func foo5(xx **int, yy *int) { // ERROR "foo5 xx does not escape$" "foo5 yy does not escape$"
+ xx = &yy // ERROR "foo5 &yy does not escape$"
}
-func foo6(xx **int, yy *int) { // ERROR "xx does not escape" "leaking param: yy"
+func foo6(xx **int, yy *int) { // ERROR "foo6 xx does not escape$" "leaking param: yy$"
*xx = yy
}
-func foo7(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+func foo7(xx **int, yy *int) { // ERROR "foo7 xx does not escape$" "foo7 yy does not escape$"
**xx = *yy
}
-func foo8(xx, yy *int) int { // ERROR "xx does not escape" "yy does not escape"
+func foo8(xx, yy *int) int { // ERROR "foo8 xx does not escape$" "foo8 yy does not escape$"
xx = yy
return *xx
}
-func foo9(xx, yy *int) *int { // ERROR "leaking param: xx" "leaking param: yy"
+func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r2 level=0$" "leaking param: yy to result ~r2 level=0$"
xx = yy
return xx
}
-func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+func foo10(xx, yy *int) { // ERROR "foo10 xx does not escape$" "foo10 yy does not escape$"
*xx = *yy
}
func foo11() int {
x, y := 0, 42
- xx := &x // ERROR "&x does not escape"
- yy := &y // ERROR "&y does not escape"
+ xx := &x // ERROR "foo11 &x does not escape$"
+ yy := &y // ERROR "foo11 &y does not escape$"
*xx = *yy
return x
}
var xxx **int
-func foo12(yyy **int) { // ERROR "leaking param: yyy"
+func foo12(yyy **int) { // ERROR "leaking param: yyy$"
xxx = yyy
}
// Must treat yyy as leaking because *yyy leaks, and the escape analysis
// summaries in exported metadata do not distinguish these two cases.
-func foo13(yyy **int) { // ERROR "leaking param: yyy"
+func foo13(yyy **int) { // ERROR "leaking param content: yyy$"
*xxx = *yyy
}
-func foo14(yyy **int) { // ERROR "yyy does not escape"
+func foo14(yyy **int) { // ERROR "foo14 yyy does not escape$"
**xxx = **yyy
}
-func foo15(yy *int) { // ERROR "moved to heap: yy"
- xxx = &yy // ERROR "&yy escapes to heap"
+func foo15(yy *int) { // ERROR "moved to heap: yy$"
+ xxx = &yy // ERROR "&yy escapes to heap$"
}
-func foo16(yy *int) { // ERROR "leaking param: yy"
+func foo16(yy *int) { // ERROR "leaking param: yy$"
*xxx = yy
}
-func foo17(yy *int) { // ERROR "yy does not escape"
+func foo17(yy *int) { // ERROR "foo17 yy does not escape$"
**xxx = *yy
}
-func foo18(y int) { // ERROR "moved to heap: "y"
- *xxx = &y // ERROR "&y escapes to heap"
+func foo18(y int) { // ERROR "moved to heap: y$"
+ *xxx = &y // ERROR "&y escapes to heap$"
}
func foo19(y int) {
@@ -118,52 +118,52 @@ type Bar struct {
}
func NewBar() *Bar {
- return &Bar{42, nil} // ERROR "&Bar literal escapes to heap"
+ return &Bar{42, nil} // ERROR "&Bar literal escapes to heap$"
}
-func NewBarp(x *int) *Bar { // ERROR "leaking param: x"
- return &Bar{42, x} // ERROR "&Bar literal escapes to heap"
+func NewBarp(x *int) *Bar { // ERROR "leaking param: x to result ~r1 level=-1$"
+ return &Bar{42, x} // ERROR "&Bar literal escapes to heap$"
}
-func NewBarp2(x *int) *Bar { // ERROR "x does not escape"
- return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap"
+func NewBarp2(x *int) *Bar { // ERROR "NewBarp2 x does not escape$"
+ return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap$"
}
-func (b *Bar) NoLeak() int { // ERROR "b does not escape"
+func (b *Bar) NoLeak() int { // ERROR "\(\*Bar\).NoLeak b does not escape$"
return *(b.ii)
}
-func (b *Bar) Leak() *int { // ERROR "leaking param: b"
- return &b.i // ERROR "&b.i escapes to heap"
+func (b *Bar) Leak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
+ return &b.i // ERROR "&b.i escapes to heap$"
}
-func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param b content to result ~r0"
+func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param: b to result ~r0 level=1$"
return b.ii
}
-func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b"
+func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
return b.ii
}
-func (b Bar) LeaksToo() *int { // ERROR "leaking param: b"
- v := 0 // ERROR "moved to heap: v"
- b.ii = &v // ERROR "&v escapes"
+func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$"
+ v := 0 // ERROR "moved to heap: v$"
+ b.ii = &v // ERROR "&v escapes to heap$"
return b.ii
}
-func (b *Bar) LeaksABit() *int { // ERROR "leaking param b content to result ~r0"
- v := 0 // ERROR "moved to heap: v"
- b.ii = &v // ERROR "&v escapes"
+func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$"
+ v := 0 // ERROR "moved to heap: v$"
+ b.ii = &v // ERROR "&v escapes to heap$"
return b.ii
}
-func (b Bar) StillNoLeak() int { // ERROR "b does not escape"
+func (b Bar) StillNoLeak() int { // ERROR "Bar.StillNoLeak b does not escape$"
v := 0
- b.ii = &v // ERROR "&v does not escape"
+ b.ii = &v // ERROR "Bar.StillNoLeak &v does not escape$"
return b.i
}
-func goLeak(b *Bar) { // ERROR "leaking param: b"
+func goLeak(b *Bar) { // ERROR "leaking param: b$"
go b.NoLeak()
}
@@ -173,90 +173,105 @@ type Bar2 struct {
}
func NewBar2() *Bar2 {
- return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap"
+ return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap$"
}
-func (b *Bar2) NoLeak() int { // ERROR "b does not escape"
+func (b *Bar2) NoLeak() int { // ERROR "\(\*Bar2\).NoLeak b does not escape$"
return b.i[0]
}
-func (b *Bar2) Leak() []int { // ERROR "leaking param: b"
- return b.i[:] // ERROR "b.i escapes to heap"
+func (b *Bar2) Leak() []int { // ERROR "leaking param: b to result ~r0 level=0$"
+ return b.i[:] // ERROR "b.i escapes to heap$"
}
-func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param b content to result ~r0"
+func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param: b to result ~r0 level=1$"
return b.ii[0:1]
}
-func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape"
+func (b Bar2) AgainNoLeak() [12]int { // ERROR "Bar2.AgainNoLeak b does not escape$"
return b.i
}
-func (b *Bar2) LeakSelf() { // ERROR "leaking param: b"
- b.ii = b.i[0:4] // ERROR "b.i escapes to heap"
+func (b *Bar2) LeakSelf() { // ERROR "leaking param: b$"
+ b.ii = b.i[0:4] // ERROR "b.i escapes to heap$"
}
-func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b"
+func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b$"
var buf []int
- buf = b.i[0:] // ERROR "b.i escapes to heap"
+ buf = b.i[0:] // ERROR "b.i escapes to heap$"
b.ii = buf
}
func foo21() func() int {
- x := 42 // ERROR "moved to heap: x"
- return func() int { // ERROR "func literal escapes to heap"
- return x // ERROR "&x escapes to heap"
+ x := 42
+ return func() int { // ERROR "func literal escapes to heap$"
+ return x
+ }
+}
+
+func foo21a() func() int {
+ x := 42 // ERROR "moved to heap: x$"
+ return func() int { // ERROR "func literal escapes to heap$"
+ x++ // ERROR "&x escapes to heap$"
+ return x
}
}
func foo22() int {
x := 42
- return func() int { // ERROR "func literal does not escape"
+ return func() int { // ERROR "foo22 func literal does not escape$"
return x
}()
}
-func foo23(x int) func() int { // ERROR "moved to heap: x"
- return func() int { // ERROR "func literal escapes to heap"
- return x // ERROR "&x escapes to heap"
+func foo23(x int) func() int {
+ return func() int { // ERROR "func literal escapes to heap$"
+ return x
}
}
-func foo23a(x int) func() int { // ERROR "moved to heap: x"
- f := func() int { // ERROR "func literal escapes to heap"
- return x // ERROR "&x escapes to heap"
+func foo23a(x int) func() int {
+ f := func() int { // ERROR "func literal escapes to heap$"
+ return x
}
return f
}
-func foo23b(x int) *(func() int) { // ERROR "moved to heap: x"
- f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" "&x escapes to heap"
- return &f // ERROR "&f escapes to heap"
+func foo23b(x int) *(func() int) {
+ f := func() int { return x } // ERROR "func literal escapes to heap$" "moved to heap: f$"
+ return &f // ERROR "&f escapes to heap$"
+}
+
+func foo23c(x int) func() int { // ERROR "moved to heap: x$"
+ return func() int { // ERROR "func literal escapes to heap$"
+ x++ // ERROR "&x escapes to heap$"
+ return x
+ }
}
func foo24(x int) int {
- return func() int { // ERROR "func literal does not escape"
+ return func() int { // ERROR "foo24 func literal does not escape$"
return x
}()
}
var x *int
-func fooleak(xx *int) int { // ERROR "leaking param: xx"
+func fooleak(xx *int) int { // ERROR "leaking param: xx$"
x = xx
return *x
}
-func foonoleak(xx *int) int { // ERROR "xx does not escape"
+func foonoleak(xx *int) int { // ERROR "foonoleak xx does not escape$"
return *x + *xx
}
-func foo31(x int) int { // ERROR "moved to heap: x"
- return fooleak(&x) // ERROR "&x escapes to heap"
+func foo31(x int) int { // ERROR "moved to heap: x$"
+ return fooleak(&x) // ERROR "&x escapes to heap$"
}
func foo32(x int) int {
- return foonoleak(&x) // ERROR "&x does not escape"
+ return foonoleak(&x) // ERROR "foo32 &x does not escape$"
}
type Foo struct {
@@ -267,114 +282,114 @@ type Foo struct {
var F Foo
var pf *Foo
-func (f *Foo) fooleak() { // ERROR "leaking param: f"
+func (f *Foo) fooleak() { // ERROR "leaking param: f$"
pf = f
}
-func (f *Foo) foonoleak() { // ERROR "f does not escape"
+func (f *Foo) foonoleak() { // ERROR "\(\*Foo\).foonoleak f does not escape$"
F.x = f.x
}
-func (f *Foo) Leak() { // ERROR "leaking param: f"
+func (f *Foo) Leak() { // ERROR "leaking param: f$"
f.fooleak()
}
-func (f *Foo) NoLeak() { // ERROR "f does not escape"
+func (f *Foo) NoLeak() { // ERROR "\(\*Foo\).NoLeak f does not escape$"
f.foonoleak()
}
-func foo41(x int) { // ERROR "moved to heap: x"
- F.xx = &x // ERROR "&x escapes to heap"
+func foo41(x int) { // ERROR "moved to heap: x$"
+ F.xx = &x // ERROR "&x escapes to heap$"
}
-func (f *Foo) foo42(x int) { // ERROR "f does not escape" "moved to heap: x"
- f.xx = &x // ERROR "&x escapes to heap"
+func (f *Foo) foo42(x int) { // ERROR "\(\*Foo\).foo42 f does not escape$" "moved to heap: x$"
+ f.xx = &x // ERROR "&x escapes to heap$"
}
-func foo43(f *Foo, x int) { // ERROR "f does not escape" "moved to heap: x"
- f.xx = &x // ERROR "&x escapes to heap"
+func foo43(f *Foo, x int) { // ERROR "foo43 f does not escape$" "moved to heap: x$"
+ f.xx = &x // ERROR "&x escapes to heap$"
}
-func foo44(yy *int) { // ERROR "leaking param: yy"
+func foo44(yy *int) { // ERROR "leaking param: yy$"
F.xx = yy
}
-func (f *Foo) foo45() { // ERROR "f does not escape"
+func (f *Foo) foo45() { // ERROR "\(\*Foo\).foo45 f does not escape$"
F.x = f.x
}
// See foo13 above for explanation of why f leaks.
-func (f *Foo) foo46() { // ERROR "leaking param: f"
+func (f *Foo) foo46() { // ERROR "leaking param content: f$"
F.xx = f.xx
}
-func (f *Foo) foo47() { // ERROR "leaking param: f"
- f.xx = &f.x // ERROR "&f.x escapes to heap"
+func (f *Foo) foo47() { // ERROR "leaking param: f$"
+ f.xx = &f.x // ERROR "&f.x escapes to heap$"
}
var ptrSlice []*int
-func foo50(i *int) { // ERROR "leaking param: i"
+func foo50(i *int) { // ERROR "leaking param: i$"
ptrSlice[0] = i
}
var ptrMap map[*int]*int
-func foo51(i *int) { // ERROR "leaking param: i"
+func foo51(i *int) { // ERROR "leaking param: i$"
ptrMap[i] = i
}
-func indaddr1(x int) *int { // ERROR "moved to heap: x"
- return &x // ERROR "&x escapes to heap"
+func indaddr1(x int) *int { // ERROR "moved to heap: x$"
+ return &x // ERROR "&x escapes to heap$"
}
-func indaddr2(x *int) *int { // ERROR "leaking param: x"
- return *&x // ERROR "&x does not escape"
+func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
+ return *&x // ERROR "indaddr2 &x does not escape$"
}
-func indaddr3(x *int32) *int { // ERROR "leaking param: x"
- return *(**int)(unsafe.Pointer(&x)) // ERROR "&x does not escape"
+func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r1 level=0$"
+ return *(**int)(unsafe.Pointer(&x)) // ERROR "indaddr3 &x does not escape$"
}
// From package math:
func Float32bits(f float32) uint32 {
- return *(*uint32)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+ return *(*uint32)(unsafe.Pointer(&f)) // ERROR "Float32bits &f does not escape$"
}
func Float32frombits(b uint32) float32 {
- return *(*float32)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+ return *(*float32)(unsafe.Pointer(&b)) // ERROR "Float32frombits &b does not escape$"
}
func Float64bits(f float64) uint64 {
- return *(*uint64)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+ return *(*uint64)(unsafe.Pointer(&f)) // ERROR "Float64bits &f does not escape$"
}
func Float64frombits(b uint64) float64 {
- return *(*float64)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+ return *(*float64)(unsafe.Pointer(&b)) // ERROR "Float64frombits &b does not escape$"
}
// contrast with
-func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f"
- return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap"
+func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f$"
+ return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap$"
}
-func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f"
+func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r1 level=0$"
return (*uint64)(unsafe.Pointer(f))
}
-func typesw(i interface{}) *int { // ERROR "leaking param: i"
+func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r1 level=0$"
switch val := i.(type) {
case *int:
return val
case *int8:
- v := int(*val) // ERROR "moved to heap: v"
- return &v // ERROR "&v escapes to heap"
+ v := int(*val) // ERROR "moved to heap: v$"
+ return &v // ERROR "&v escapes to heap$"
}
return nil
}
-func exprsw(i *int) *int { // ERROR "leaking param: i"
+func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
switch j := i; *j + 110 {
case 12:
return j
@@ -386,20 +401,20 @@ func exprsw(i *int) *int { // ERROR "leaking param: i"
}
// assigning to an array element is like assigning to the array
-func foo60(i *int) *int { // ERROR "leaking param: i"
+func foo60(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
var a [12]*int
a[0] = i
return a[1]
}
-func foo60a(i *int) *int { // ERROR "i does not escape"
+func foo60a(i *int) *int { // ERROR "foo60a i does not escape$"
var a [12]*int
a[0] = i
return nil
}
// assigning to a struct field is like assigning to the struct
-func foo61(i *int) *int { // ERROR "leaking param: i"
+func foo61(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
type S struct {
a, b *int
}
@@ -408,7 +423,7 @@ func foo61(i *int) *int { // ERROR "leaking param: i"
return s.b
}
-func foo61a(i *int) *int { // ERROR "i does not escape"
+func foo61a(i *int) *int { // ERROR "foo61a i does not escape$"
type S struct {
a, b *int
}
@@ -420,11 +435,11 @@ func foo61a(i *int) *int { // ERROR "i does not escape"
// assigning to a struct field is like assigning to the struct but
// here this subtlety is lost, since s.a counts as an assignment to a
// track-losing dereference.
-func foo62(i *int) *int { // ERROR "leaking param: i"
+func foo62(i *int) *int { // ERROR "leaking param: i$"
type S struct {
a, b *int
}
- s := new(S) // ERROR "new[(]S[)] does not escape"
+ s := new(S) // ERROR "foo62 new\(S\) does not escape$"
s.a = i
return nil // s.b
}
@@ -433,14 +448,14 @@ type M interface {
M()
}
-func foo63(m M) { // ERROR "m does not escape"
+func foo63(m M) { // ERROR "foo63 m does not escape$"
}
-func foo64(m M) { // ERROR "leaking param: m"
+func foo64(m M) { // ERROR "leaking param: m$"
m.M()
}
-func foo64b(m M) { // ERROR "leaking param: m"
+func foo64b(m M) { // ERROR "leaking param: m$"
defer m.M()
}
@@ -450,55 +465,56 @@ func (MV) M() {}
func foo65() {
var mv MV
- foo63(&mv) // ERROR "&mv does not escape"
+ foo63(&mv) // ERROR "foo65 &mv does not escape$"
}
func foo66() {
- var mv MV // ERROR "moved to heap: mv"
- foo64(&mv) // ERROR "&mv escapes to heap"
+ var mv MV // ERROR "moved to heap: mv$"
+ foo64(&mv) // ERROR "&mv escapes to heap$"
}
func foo67() {
var mv MV
- foo63(mv)
+ foo63(mv) // ERROR "foo67 mv does not escape$"
}
func foo68() {
var mv MV
- foo64(mv) // escapes but it's an int so irrelevant
+ // escapes but it's an int so irrelevant
+ foo64(mv) // ERROR "mv escapes to heap$"
}
-func foo69(m M) { // ERROR "leaking param: m"
+func foo69(m M) { // ERROR "leaking param: m$"
foo64(m)
}
-func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m"
- m = mv1
+func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
+ m = mv1 // ERROR "mv1 escapes to heap$"
foo64(m)
}
-func foo71(x *int) []*int { // ERROR "leaking param: x"
+func foo71(x *int) []*int { // ERROR "leaking param: x$"
var y []*int
y = append(y, x)
return y
}
-func foo71a(x int) []*int { // ERROR "moved to heap: x"
+func foo71a(x int) []*int { // ERROR "moved to heap: x$"
var y []*int
- y = append(y, &x) // ERROR "&x escapes to heap"
+ y = append(y, &x) // ERROR "&x escapes to heap$"
return y
}
func foo72() {
var x int
var y [1]*int
- y[0] = &x // ERROR "&x does not escape"
+ y[0] = &x // ERROR "foo72 &x does not escape$"
}
func foo72aa() [10]*int {
- var x int // ERROR "moved to heap: x"
+ var x int // ERROR "moved to heap: x$"
var y [10]*int
- y[0] = &x // ERROR "&x escapes to heap"
+ y[0] = &x // ERROR "&x escapes to heap$"
return y
}
@@ -506,8 +522,8 @@ func foo72a() {
var y [10]*int
for i := 0; i < 10; i++ {
// escapes its scope
- x := i // ERROR "moved to heap: x"
- y[i] = &x // ERROR "&x escapes to heap"
+ x := i // ERROR "moved to heap: x$"
+ y[i] = &x // ERROR "&x escapes to heap$"
}
return
}
@@ -515,31 +531,56 @@ func foo72a() {
func foo72b() [10]*int {
var y [10]*int
for i := 0; i < 10; i++ {
- x := i // ERROR "moved to heap: x"
- y[i] = &x // ERROR "&x escapes to heap"
+ x := i // ERROR "moved to heap: x$"
+ y[i] = &x // ERROR "&x escapes to heap$"
}
return y
}
// issue 2145
func foo73() {
- s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+ s := []int{3, 2, 1} // ERROR "foo73 \[\]int literal does not escape$"
+ for _, v := range s {
+ vv := v
+ // actually just escapes its scope
+ defer func() { // ERROR "func literal escapes to heap$"
+ println(vv)
+ }()
+ }
+}
+
+func foo731() {
+ s := []int{3, 2, 1} // ERROR "foo731 \[\]int literal does not escape$"
for _, v := range s {
- vv := v // ERROR "moved to heap: vv"
+ vv := v // ERROR "moved to heap: vv$"
// actually just escapes its scope
- defer func() { // ERROR "func literal escapes to heap"
- println(vv) // ERROR "&vv escapes to heap"
+ defer func() { // ERROR "func literal escapes to heap$"
+ vv = 42 // ERROR "&vv escapes to heap$"
+ println(vv)
}()
}
}
func foo74() {
- s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+ s := []int{3, 2, 1} // ERROR "foo74 \[\]int literal does not escape$"
for _, v := range s {
- vv := v // ERROR "moved to heap: vv"
+ vv := v
// actually just escapes its scope
- fn := func() { // ERROR "func literal escapes to heap"
- println(vv) // ERROR "&vv escapes to heap"
+ fn := func() { // ERROR "func literal escapes to heap$"
+ println(vv)
+ }
+ defer fn()
+ }
+}
+
+func foo74a() {
+ s := []int{3, 2, 1} // ERROR "foo74a \[\]int literal does not escape$"
+ for _, v := range s {
+ vv := v // ERROR "moved to heap: vv$"
+ // actually just escapes its scope
+ fn := func() { // ERROR "func literal escapes to heap$"
+ vv += 1 // ERROR "&vv escapes to heap$"
+ println(vv)
}
defer fn()
}
@@ -548,110 +589,142 @@ func foo74() {
// issue 3975
func foo74b() {
var array [3]func()
- s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+ s := []int{3, 2, 1} // ERROR "foo74b \[\]int literal does not escape$"
for i, v := range s {
- vv := v // ERROR "moved to heap: vv"
+ vv := v
// actually just escapes its scope
- array[i] = func() { // ERROR "func literal escapes to heap"
- println(vv) // ERROR "&vv escapes to heap"
+ array[i] = func() { // ERROR "func literal escapes to heap$"
+ println(vv)
}
}
}
-func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y"
+func foo74c() {
+ var array [3]func()
+ s := []int{3, 2, 1} // ERROR "foo74c \[\]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$" "foo74c.func1 &vv does not escape$"
+ }
+ }
+}
+
+func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2 level=0$" "myprint x does not escape$"
return y
}
-func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x"
- return &x[0] // ERROR "&x.0. escapes to heap"
+func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2 level=0$" "myprint1 y does not escape$"
+ return &x[0] // ERROR "&x\[0\] escapes to heap$"
}
-func foo75(z *int) { // ERROR "z does not escape"
- myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+func foo75(z *int) { // ERROR "foo75 z does not escape$"
+ myprint(z, 1, 2, 3) // ERROR "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "foo75 ... argument does not escape$"
}
-func foo75a(z *int) { // ERROR "z does not escape"
- myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+func foo75a(z *int) { // ERROR "foo75a z does not escape$"
+ myprint1(z, 1, 2, 3) // ERROR "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "foo75a ... argument does not escape$"
}
-func foo75esc(z *int) { // ERROR "leaking param: z"
- gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+func foo75esc(z *int) { // ERROR "leaking param: z$"
+ gxx = myprint(z, 1, 2, 3) // ERROR "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "foo75esc ... argument does not escape$"
}
-func foo75aesc(z *int) { // ERROR "z does not escape"
+func foo75aesc(z *int) { // ERROR "foo75aesc z does not escape$"
var ppi **interface{} // assignments to pointer dereferences lose track
- *ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+ *ppi = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
+}
+
+func foo75aesc1(z *int) { // ERROR "foo75aesc1 z does not escape$"
+ sink = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "myprint1\(z, 1, 2, 3\) escapes to heap$"
}
-func foo76(z *int) { // ERROR "leaking param: z"
- myprint(nil, z) // ERROR "[.][.][.] argument does not escape"
+// BAD: z does not escape here
+func foo76(z *int) { // ERROR "leaking param: z$"
+ myprint(nil, z) // ERROR "foo76 ... argument does not escape$" "z escapes to heap$"
}
-func foo76a(z *int) { // ERROR "leaking param: z"
- myprint1(nil, z) // ERROR "[.][.][.] argument does not escape"
+// BAD: z does not escape here
+func foo76a(z *int) { // ERROR "leaking param: z$"
+ myprint1(nil, z) // ERROR "foo76a ... argument does not escape$" "z escapes to heap$"
}
func foo76b() {
- myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+ myprint(nil, 1, 2, 3) // ERROR "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "foo76b ... argument does not escape$"
}
func foo76c() {
- myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+ myprint1(nil, 1, 2, 3) // ERROR "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "foo76c ... argument does not escape$"
}
func foo76d() {
- defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+ defer myprint(nil, 1, 2, 3) // ERROR "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "foo76d ... argument does not escape$"
}
func foo76e() {
- defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+ defer myprint1(nil, 1, 2, 3) // ERROR "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$" "foo76e ... argument does not escape$"
}
func foo76f() {
for {
// TODO: This one really only escapes its scope, but we don't distinguish yet.
- defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+ defer myprint(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
}
}
func foo76g() {
for {
- defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+ defer myprint1(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
}
}
-func foo77(z []interface{}) { // ERROR "z does not escape"
+func foo77(z []interface{}) { // ERROR "foo77 z does not escape$"
myprint(nil, z...) // z does not escape
}
-func foo77a(z []interface{}) { // ERROR "z does not escape"
+func foo77a(z []interface{}) { // ERROR "foo77a z does not escape$"
myprint1(nil, z...)
}
-func foo77b(z []interface{}) { // ERROR "leaking param: z"
+func foo77b(z []interface{}) { // ERROR "leaking param: z$"
var ppi **interface{}
*ppi = myprint1(nil, z...)
}
-func foo78(z int) *int { // ERROR "moved to heap: z"
- return &z // ERROR "&z escapes to heap"
+func foo77c(z []interface{}) { // ERROR "leaking param: z$"
+ sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z...\) escapes to heap$"
}
-func foo78a(z int) *int { // ERROR "moved to heap: z"
- y := &z // ERROR "&z escapes to heap"
- x := &y // ERROR "&y does not escape"
+func dotdotdot() {
+ // BAD: i should not escape here
+ i := 0 // ERROR "moved to heap: i$"
+ myprint(nil, &i) // ERROR "&i escapes to heap$" "dotdotdot ... argument does not escape$"
+
+ // BAD: j should not escape here
+ j := 0 // ERROR "moved to heap: j$"
+ myprint1(nil, &j) // ERROR "&j escapes to heap$" "dotdotdot ... argument does not escape$"
+}
+
+func foo78(z int) *int { // ERROR "moved to heap: z$"
+ return &z // ERROR "&z escapes to heap$"
+}
+
+func foo78a(z int) *int { // ERROR "moved to heap: z$"
+ y := &z // ERROR "&z escapes to heap$"
+ x := &y // ERROR "foo78a &y does not escape$"
return *x // really return y
}
func foo79() *int {
- return new(int) // ERROR "new[(]int[)] escapes to heap"
+ return new(int) // ERROR "new\(int\) escapes to heap$"
}
func foo80() *int {
var z *int
for {
// Really just escapes its scope but we don't distinguish
- z = new(int) // ERROR "new[(]int[)] escapes to heap"
+ z = new(int) // ERROR "new\(int\) escapes to heap$"
}
_ = z
return nil
@@ -659,24 +732,24 @@ func foo80() *int {
func foo81() *int {
for {
- z := new(int) // ERROR "new[(]int[)] does not escape"
+ z := new(int) // ERROR "foo81 new\(int\) does not escape$"
_ = z
}
return nil
}
-func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param"
+func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param: p to result x level=0$" "leaking param: p to result y level=0$"
-func noop(x, y *int) {} // ERROR "does not escape"
+func noop(x, y *int) {} // ERROR "noop x does not escape$" "noop y does not escape$"
func foo82() {
- var x, y, z int // ERROR "moved to heap"
- go noop(tee(&z)) // ERROR "&z escapes to heap"
- go noop(&x, &y) // ERROR "escapes to heap"
+ var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$"
+ go noop(tee(&z)) // ERROR "&z escapes to heap$"
+ go noop(&x, &y) // ERROR "&x escapes to heap$" "&y escapes to heap$"
for {
- var u, v, w int // ERROR "moved to heap"
- defer noop(tee(&u)) // ERROR "&u escapes to heap"
- defer noop(&v, &w) // ERROR "escapes to heap"
+ var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$"
+ defer noop(tee(&u)) // ERROR "&u escapes to heap$"
+ defer noop(&v, &w) // ERROR "&v escapes to heap$" "&w escapes to heap$"
}
}
@@ -689,24 +762,24 @@ type LimitedFooer struct {
N int64
}
-func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r"
- return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap"
+func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r to result ~r2 level=-1$"
+ return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap$"
}
-func foo90(x *int) map[*int]*int { // ERROR "leaking param: x"
- return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap"
+func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
+ return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
}
-func foo91(x *int) map[*int]*int { // ERROR "leaking param: x"
- return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap"
+func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
+ return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
}
-func foo92(x *int) [2]*int { // ERROR "leaking param: x"
+func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
return [2]*int{x, nil}
}
// does not leak c
-func foo93(c chan *int) *int { // ERROR "c does not escape"
+func foo93(c chan *int) *int { // ERROR "foo93 c does not escape$"
for v := range c {
return v
}
@@ -714,7 +787,7 @@ func foo93(c chan *int) *int { // ERROR "c does not escape"
}
// does not leak m
-func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
+func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r2 level=1"
for k, v := range m {
if b {
return k
@@ -725,32 +798,32 @@ func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
}
// does leak x
-func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape" "leaking param: x"
+func foo95(m map[*int]*int, x *int) { // ERROR "foo95 m does not escape$" "leaking param: x$"
m[x] = x
}
-// does not leak m
-func foo96(m []*int) *int { // ERROR "m does not escape"
+// does not leak m but does leak content
+func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
return m[0]
}
// does leak m
-func foo97(m [1]*int) *int { // ERROR "leaking param: m"
+func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
return m[0]
}
// does not leak m
-func foo98(m map[int]*int) *int { // ERROR "m does not escape"
+func foo98(m map[int]*int) *int { // ERROR "foo98 m does not escape$"
return m[0]
}
// does leak m
-func foo99(m *[1]*int) []*int { // ERROR "leaking param: m"
+func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r1 level=0$"
return m[:]
}
// does not leak m
-func foo100(m []*int) *int { // ERROR "m does not escape"
+func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
for _, v := range m {
return v
}
@@ -758,7 +831,7 @@ func foo100(m []*int) *int { // ERROR "m does not escape"
}
// does leak m
-func foo101(m [1]*int) *int { // ERROR "leaking param: m"
+func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
for _, v := range m {
return v
}
@@ -766,109 +839,109 @@ func foo101(m [1]*int) *int { // ERROR "leaking param: m"
}
// does not leak m
-func foo101a(m [1]*int) *int { // ERROR "m does not escape"
- for i := range m { // ERROR "moved to heap: i"
- return &i // ERROR "&i escapes to heap"
+func foo101a(m [1]*int) *int { // ERROR "foo101a m does not escape$"
+ for i := range m { // ERROR "moved to heap: i$"
+ return &i // ERROR "&i escapes to heap$"
}
return nil
}
// does leak x
-func foo102(m []*int, x *int) { // ERROR "m does not escape" "leaking param: x"
+func foo102(m []*int, x *int) { // ERROR "foo102 m does not escape$" "leaking param: x$"
m[0] = x
}
// does not leak x
-func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape"
+func foo103(m [1]*int, x *int) { // ERROR "foo103 m does not escape$" "foo103 x does not escape$"
m[0] = x
}
var y []*int
-// does not leak x
-func foo104(x []*int) { // ERROR "x does not escape"
+// does not leak x but does leak content
+func foo104(x []*int) { // ERROR "leaking param content: x"
copy(y, x)
}
-// does not leak x
-func foo105(x []*int) { // ERROR "x does not escape"
+// does not leak x but does leak content
+func foo105(x []*int) { // ERROR "leaking param content: x"
_ = append(y, x...)
}
// does leak x
-func foo106(x *int) { // ERROR "leaking param: x"
+func foo106(x *int) { // ERROR "leaking param: x$"
_ = append(y, x)
}
-func foo107(x *int) map[*int]*int { // ERROR "leaking param: x"
- return map[*int]*int{x: nil} // ERROR "map.* literal escapes to heap"
+func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
+ return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
}
-func foo108(x *int) map[*int]*int { // ERROR "leaking param: x"
- return map[*int]*int{nil: x} // ERROR "map.* literal escapes to heap"
+func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
+ return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
}
-func foo109(x *int) *int { // ERROR "leaking param: x"
- m := map[*int]*int{x: nil} // ERROR "map.* literal does not escape"
+func foo109(x *int) *int { // ERROR "leaking param: x$"
+ m := map[*int]*int{x: nil} // ERROR "foo109 map\[\*int\]\*int literal does not escape$"
for k, _ := range m {
return k
}
return nil
}
-func foo110(x *int) *int { // ERROR "leaking param: x"
- m := map[*int]*int{nil: x} // ERROR "map.* literal does not escape"
+func foo110(x *int) *int { // ERROR "leaking param: x$"
+ m := map[*int]*int{nil: x} // ERROR "foo110 map\[\*int\]\*int literal does not escape$"
return m[nil]
}
-func foo111(x *int) *int { // ERROR "leaking param: x"
- m := []*int{x} // ERROR "\[\]\*int literal does not escape"
+func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
+ m := []*int{x} // ERROR "foo111 \[\]\*int literal does not escape$"
return m[0]
}
-func foo112(x *int) *int { // ERROR "leaking param: x"
+func foo112(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
m := [1]*int{x}
return m[0]
}
-func foo113(x *int) *int { // ERROR "leaking param: x"
+func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
m := Bar{ii: x}
return m.ii
}
-func foo114(x *int) *int { // ERROR "leaking param: x"
- m := &Bar{ii: x} // ERROR "&Bar literal does not escape"
+func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
+ m := &Bar{ii: x} // ERROR "foo114 &Bar literal does not escape$"
return m.ii
}
-func foo115(x *int) *int { // ERROR "leaking param: x"
+func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
}
func foo116(b bool) *int {
if b {
- x := 1 // ERROR "moved to heap: x"
- return &x // ERROR "&x escapes to heap"
+ x := 1 // ERROR "moved to heap: x$"
+ return &x // ERROR "&x escapes to heap$"
} else {
- y := 1 // ERROR "moved to heap: y"
- return &y // ERROR "&y escapes to heap"
+ y := 1 // ERROR "moved to heap: y$"
+ return &y // ERROR "&y escapes to heap$"
}
return nil
}
-func foo117(unknown func(interface{})) { // ERROR "unknown does not escape"
- x := 1 // ERROR "moved to heap: x"
- unknown(&x) // ERROR "&x escapes to heap"
+func foo117(unknown func(interface{})) { // ERROR "foo117 unknown does not escape$"
+ x := 1 // ERROR "moved to heap: x$"
+ unknown(&x) // ERROR "&x escapes to heap$"
}
-func foo118(unknown func(*int)) { // ERROR "unknown does not escape"
- x := 1 // ERROR "moved to heap: x"
- unknown(&x) // ERROR "&x escapes to heap"
+func foo118(unknown func(*int)) { // ERROR "foo118 unknown does not escape$"
+ x := 1 // ERROR "moved to heap: x$"
+ unknown(&x) // ERROR "&x escapes to heap$"
}
func external(*int)
-func foo119(x *int) { // ERROR "leaking param: x"
+func foo119(x *int) { // ERROR "leaking param: x$"
external(x)
}
@@ -1079,16 +1152,16 @@ L100:
func foo121() {
for i := 0; i < 10; i++ {
- defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
- go myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
+ defer myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
+ go myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
}
}
// same as foo121 but check across import
func foo121b() {
for i := 0; i < 10; i++ {
- defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
- go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
+ defer fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
+ go fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
}
}
@@ -1098,7 +1171,7 @@ func foo122() {
goto L1
L1:
- i = new(int) // ERROR "new.int. does not escape"
+ i = new(int) // ERROR "foo122 new\(int\) does not escape$"
_ = i
}
@@ -1107,25 +1180,25 @@ func foo123() {
var i *int
L1:
- i = new(int) // ERROR "new.int. escapes to heap"
+ i = new(int) // ERROR "new\(int\) escapes to heap$"
goto L1
_ = i
}
-func foo124(x **int) { // ERROR "x does not escape"
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes"
- func() { // ERROR "func literal does not escape"
- *x = p // ERROR "leaking closure reference p"
+func foo124(x **int) { // ERROR "foo124 x does not escape$"
+ var i int // ERROR "moved to heap: i$"
+ p := &i // ERROR "&i escapes to heap$"
+ func() { // ERROR "foo124 func literal does not escape$"
+ *x = p // ERROR "leaking closure reference p$"
}()
}
-func foo125(ch chan *int) { // ERROR "does not escape"
- var i int // ERROR "moved to heap"
- p := &i // ERROR "&i escapes to heap"
- func() { // ERROR "func literal does not escape"
- ch <- p // ERROR "leaking closure reference p"
+func foo125(ch chan *int) { // ERROR "foo125 ch does not escape$"
+ var i int // ERROR "moved to heap: i$"
+ p := &i // ERROR "&i escapes to heap$"
+ func() { // ERROR "foo125 func literal does not escape$"
+ ch <- p // ERROR "leaking closure reference p$"
}()
}
@@ -1133,9 +1206,9 @@ func foo126() {
var px *int // loopdepth 0
for {
// loopdepth 1
- var i int // ERROR "moved to heap"
- func() { // ERROR "func literal does not escape"
- px = &i // ERROR "&i escapes"
+ var i int // ERROR "moved to heap: i$"
+ func() { // ERROR "foo126 func literal does not escape$"
+ px = &i // ERROR "&i escapes to heap$"
}()
}
_ = px
@@ -1144,26 +1217,26 @@ func foo126() {
var px *int
func foo127() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap"
+ var i int // ERROR "moved to heap: i$"
+ p := &i // ERROR "&i escapes to heap$"
q := p
px = q
}
func foo128() {
var i int
- p := &i // ERROR "&i does not escape"
+ p := &i // ERROR "foo128 &i does not escape$"
q := p
_ = q
}
func foo129() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap"
- func() { // ERROR "func literal does not escape"
- q := p // ERROR "leaking closure reference p"
- func() { // ERROR "func literal does not escape"
- r := q // ERROR "leaking closure reference q"
+ var i int // ERROR "moved to heap: i$"
+ p := &i // ERROR "&i escapes to heap$"
+ func() { // ERROR "foo129 func literal does not escape$"
+ q := p // ERROR "leaking closure reference p$"
+ func() { // ERROR "foo129.func1 func literal does not escape$"
+ r := q // ERROR "leaking closure reference q$"
px = r
}()
}()
@@ -1171,40 +1244,40 @@ func foo129() {
func foo130() {
for {
- var i int // ERROR "moved to heap"
- func() { // ERROR "func literal does not escape"
- px = &i // ERROR "&i escapes" "leaking closure reference i"
+ var i int // ERROR "moved to heap: i$"
+ func() { // ERROR "foo130 func literal does not escape$"
+ px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$"
}()
}
}
func foo131() {
- var i int // ERROR "moved to heap"
- func() { // ERROR "func literal does not escape"
- px = &i // ERROR "&i escapes" "leaking closure reference i"
+ var i int // ERROR "moved to heap: i$"
+ func() { // ERROR "foo131 func literal does not escape$"
+ px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$"
}()
}
func foo132() {
- var i int // ERROR "moved to heap"
- go func() { // ERROR "func literal escapes to heap"
- px = &i // ERROR "&i escapes" "leaking closure reference i"
+ var i int // ERROR "moved to heap: i$"
+ go func() { // ERROR "func literal escapes to heap$"
+ px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$"
}()
}
func foo133() {
- var i int // ERROR "moved to heap"
- defer func() { // ERROR "func literal does not escape"
- px = &i // ERROR "&i escapes" "leaking closure reference i"
+ var i int // ERROR "moved to heap: i$"
+ defer func() { // ERROR "foo133 func literal does not escape$"
+ px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$"
}()
}
func foo134() {
var i int
- p := &i // ERROR "&i does not escape"
- func() { // ERROR "func literal does not escape"
+ p := &i // ERROR "foo134 &i does not escape$"
+ func() { // ERROR "foo134 func literal does not escape$"
q := p
- func() { // ERROR "func literal does not escape"
+ func() { // ERROR "foo134.func1 func literal does not escape$"
r := q
_ = r
}()
@@ -1212,11 +1285,11 @@ func foo134() {
}
func foo135() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap" "moved to heap: p"
- go func() { // ERROR "func literal escapes to heap"
- q := p // ERROR "&p escapes to heap"
- func() { // ERROR "func literal does not escape"
+ var i int // ERROR "moved to heap: i$"
+ p := &i // ERROR "&i escapes to heap$"
+ go func() { // ERROR "func literal escapes to heap$"
+ q := p
+ func() { // ERROR "foo135.func1 func literal does not escape$"
r := q
_ = r
}()
@@ -1224,24 +1297,24 @@ func foo135() {
}
func foo136() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap" "moved to heap: p"
- go func() { // ERROR "func literal escapes to heap"
- q := p // ERROR "&p escapes to heap" "leaking closure reference p"
- func() { // ERROR "func literal does not escape"
- r := q // ERROR "leaking closure reference q"
+ var i int // ERROR "moved to heap: i$"
+ p := &i // ERROR "&i escapes to heap$"
+ go func() { // ERROR "func literal escapes to heap$"
+ q := p // ERROR "leaking closure reference p$"
+ func() { // ERROR "foo136.func1 func literal does not escape$"
+ r := q // ERROR "leaking closure reference q$"
px = r
}()
}()
}
func foo137() {
- var i int // ERROR "moved to heap: i"
- p := &i // ERROR "&i escapes to heap"
- func() { // ERROR "func literal does not escape"
- q := p // ERROR "leaking closure reference p" "moved to heap: q"
- go func() { // ERROR "func literal escapes to heap"
- r := q // ERROR "&q escapes to heap"
+ var i int // ERROR "moved to heap: i$"
+ p := &i // ERROR "&i escapes to heap$"
+ func() { // ERROR "foo137 func literal does not escape$"
+ q := p // ERROR "leaking closure reference p$"
+ go func() { // ERROR "func literal escapes to heap$"
+ r := q
_ = r
}()
}()
@@ -1251,8 +1324,8 @@ func foo138() *byte {
type T struct {
x [1]byte
}
- t := new(T) // ERROR "new.T. escapes to heap"
- return &t.x[0] // ERROR "&t.x.0. escapes to heap"
+ t := new(T) // ERROR "new\(T\) escapes to heap$"
+ return &t.x[0] // ERROR "&t.x\[0\] escapes to heap$"
}
func foo139() *byte {
@@ -1261,8 +1334,8 @@ func foo139() *byte {
y byte
}
}
- t := new(T) // ERROR "new.T. escapes to heap"
- return &t.x.y // ERROR "&t.x.y escapes to heap"
+ t := new(T) // ERROR "new\(T\) escapes to heap$"
+ return &t.x.y // ERROR "&t.x.y escapes to heap$"
}
// issue 4751
@@ -1274,8 +1347,8 @@ func foo140() interface{} {
X string
T *T
}
- t := &T{} // ERROR "&T literal escapes to heap"
- return U{
+ t := &T{} // ERROR "&T literal escapes to heap$"
+ return U{ // ERROR "U literal escapes to heap$"
X: t.X,
T: t,
}
@@ -1289,53 +1362,53 @@ func F2([]byte)
//go:noescape
-func F3(x []byte) // ERROR "F3 x does not escape"
+func F3(x []byte) // ERROR "F3 x does not escape$"
func F4(x []byte)
func G() {
var buf1 [10]byte
- F1(buf1[:]) // ERROR "buf1 does not escape"
+ F1(buf1[:]) // ERROR "G buf1 does not escape$"
- var buf2 [10]byte // ERROR "moved to heap: buf2"
- F2(buf2[:]) // ERROR "buf2 escapes to heap"
+ var buf2 [10]byte // ERROR "moved to heap: buf2$"
+ F2(buf2[:]) // ERROR "buf2 escapes to heap$"
var buf3 [10]byte
- F3(buf3[:]) // ERROR "buf3 does not escape"
+ F3(buf3[:]) // ERROR "G buf3 does not escape$"
- var buf4 [10]byte // ERROR "moved to heap: buf4"
- F4(buf4[:]) // ERROR "buf4 escapes to heap"
+ var buf4 [10]byte // ERROR "moved to heap: buf4$"
+ F4(buf4[:]) // ERROR "buf4 escapes to heap$"
}
type Tm struct {
x int
}
-func (t *Tm) M() { // ERROR "t does not escape"
+func (t *Tm) M() { // ERROR "\(\*Tm\).M t does not escape$"
}
func foo141() {
var f func()
- t := new(Tm) // ERROR "escapes to heap"
- f = t.M // ERROR "t.M does not escape"
+ t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
+ f = t.M // ERROR "foo141 t.M does not escape$"
_ = f
}
var gf func()
func foo142() {
- t := new(Tm) // ERROR "escapes to heap"
- gf = t.M // ERROR "t.M escapes to heap"
+ t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
+ gf = t.M // ERROR "t.M escapes to heap$"
}
// issue 3888.
func foo143() {
for i := 0; i < 1000; i++ {
- func() { // ERROR "func literal does not escape"
+ func() { // ERROR "foo143 func literal does not escape$"
for i := 0; i < 1; i++ {
var t Tm
- t.M() // ERROR "t does not escape"
+ t.M() // ERROR "foo143.func1 t does not escape$"
}
}()
}
@@ -1351,9 +1424,9 @@ func foo144a(*int)
func foo144() {
var x int
- foo144a(&x) // ERROR "&x does not escape"
+ foo144a(&x) // ERROR "foo144 &x does not escape$"
var y int
- foo144b(&y) // ERROR "&y does not escape"
+ foo144b(&y) // ERROR "foo144 &y does not escape$"
}
//go:noescape
@@ -1366,38 +1439,38 @@ type List struct {
Next *List
}
-func foo145(l List) { // ERROR "l does not escape"
+func foo145(l List) { // ERROR "foo145 l does not escape$"
var p *List
- for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+ for p = &l; p.Next != nil; p = p.Next { // ERROR "foo145 &l does not escape$"
}
}
-func foo146(l List) { // ERROR "l does not escape"
+func foo146(l List) { // ERROR "foo146 l does not escape$"
var p *List
- p = &l // ERROR "&l does not escape"
+ p = &l // ERROR "foo146 &l does not escape$"
for ; p.Next != nil; p = p.Next {
}
}
-func foo147(l List) { // ERROR "l does not escape"
+func foo147(l List) { // ERROR "foo147 l does not escape$"
var p *List
- p = &l // ERROR "&l does not escape"
+ p = &l // ERROR "foo147 &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"
+func foo148(l List) { // ERROR "foo148 l does not escape$"
+ for p := &l; p.Next != nil; p = p.Next { // ERROR "foo148 &l does not escape$"
}
}
// related: address of variable should have depth of variable, not of loop
-func foo149(l List) { // ERROR " l does not escape"
+func foo149(l List) { // ERROR "foo149 l does not escape$"
var p *List
for {
- for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+ for p = &l; p.Next != nil; p = p.Next { // ERROR "foo149 &l does not escape$"
}
}
}
@@ -1406,44 +1479,44 @@ func foo149(l List) { // ERROR " l does not escape"
var save150 []byte
-func foo150(x ...byte) { // ERROR "leaking param: x"
+func foo150(x ...byte) { // ERROR "leaking param: x$"
save150 = x
}
func bar150() {
- foo150(1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+ foo150(1, 2, 3) // ERROR "... argument escapes to heap$"
}
// issue 7931: bad handling of slice of array
var save151 *int
-func foo151(x *int) { // ERROR "leaking param: x"
+func foo151(x *int) { // ERROR "leaking param: x$"
save151 = x
}
func bar151() {
- var a [64]int // ERROR "moved to heap: a"
+ var a [64]int // ERROR "moved to heap: a$"
a[4] = 101
- foo151(&(&a)[4:8][0]) // ERROR "&\(&a\)\[4:8\]\[0\] escapes to heap" "&a escapes to heap"
+ foo151(&(&a)[4:8][0]) // ERROR "&\(&a\)\[4:8\]\[0\] escapes to heap$" "&a escapes to heap$"
}
func bar151b() {
- var a [10]int // ERROR "moved to heap: a"
- b := a[:] // ERROR "a escapes to heap"
- foo151(&b[4:8][0]) // ERROR "&b\[4:8\]\[0\] escapes to heap"
+ var a [10]int // ERROR "moved to heap: a$"
+ b := a[:] // ERROR "a escapes to heap$"
+ foo151(&b[4:8][0]) // ERROR "&b\[4:8\]\[0\] escapes to heap$"
}
func bar151c() {
- var a [64]int // ERROR "moved to heap: a"
+ var a [64]int // ERROR "moved to heap: a$"
a[4] = 101
- foo151(&(&a)[4:8:8][0]) // ERROR "&\(&a\)\[4:8:8\]\[0\] escapes to heap" "&a escapes to heap"
+ foo151(&(&a)[4:8:8][0]) // ERROR "&\(&a\)\[4:8:8\]\[0\] escapes to heap$" "&a escapes to heap$"
}
func bar151d() {
- var a [10]int // ERROR "moved to heap: a"
- b := a[:] // ERROR "a escapes to heap"
- foo151(&b[4:8:8][0]) // ERROR "&b\[4:8:8\]\[0\] escapes to heap"
+ var a [10]int // ERROR "moved to heap: a$"
+ b := a[:] // ERROR "a escapes to heap$"
+ foo151(&b[4:8:8][0]) // ERROR "&b\[4:8:8\]\[0\] escapes to heap$"
}
// issue 8120
@@ -1452,7 +1525,7 @@ type U struct {
s *string
}
-func (u *U) String() *string { // ERROR "leaking param u content to result ~r0"
+func (u *U) String() *string { // ERROR "leaking param: u to result ~r0 level=1$"
return u.s
}
@@ -1460,35 +1533,298 @@ type V struct {
s *string
}
-func NewV(u U) *V { // ERROR "leaking param: u"
- return &V{u.String()} // ERROR "&V literal escapes to heap" "u does not escape"
+// BAD -- level of leak ought to be 0
+func NewV(u U) *V { // ERROR "leaking param: u to result ~r1 level=-1"
+ return &V{u.String()} // ERROR "&V literal escapes to heap$" "NewV u does not escape"
}
func foo152() {
- a := "a" // ERROR "moved to heap: a"
- u := U{&a} // ERROR "&a escapes to heap"
+ a := "a" // ERROR "moved to heap: a$"
+ u := U{&a} // ERROR "&a escapes to heap$"
v := NewV(u)
println(v)
}
// issue 8176 - &x in type switch body not marked as escaping
-func foo153(v interface{}) *int { // ERROR "leaking param: v"
+func foo153(v interface{}) *int { // ERROR "leaking param: v to result ~r1 level=-1$"
switch x := v.(type) {
- case int: // ERROR "moved to heap: x"
- return &x // ERROR "&x escapes to heap"
+ case int: // ERROR "moved to heap: x$"
+ return &x // ERROR "&x escapes to heap$"
}
panic(0)
}
// issue 8185 - &result escaping into result
-func f() (x int, y *int) { // ERROR "moved to heap: x"
- y = &x // ERROR "&x escapes to heap"
+func f() (x int, y *int) { // ERROR "moved to heap: x$"
+ y = &x // ERROR "&x escapes to heap$"
return
}
-func g() (x interface{}) { // ERROR "moved to heap: x"
- x = &x // ERROR "&x escapes to heap"
+func g() (x interface{}) { // ERROR "moved to heap: x$"
+ x = &x // ERROR "&x escapes to heap$"
return
}
+
+var sink interface{}
+
+type Lit struct {
+ p *int
+}
+
+func ptrlitNoescape() {
+ // Both literal and element do not escape.
+ i := 0
+ x := &Lit{&i} // ERROR "ptrlitNoescape &Lit literal does not escape$" "ptrlitNoescape &i does not escape$"
+ _ = x
+}
+
+func ptrlitNoEscape2() {
+ // Literal does not escape, but element does.
+ i := 0 // ERROR "moved to heap: i$"
+ x := &Lit{&i} // ERROR "&i escapes to heap$" "ptrlitNoEscape2 &Lit literal does not escape$"
+ sink = *x // ERROR "\*x escapes to heap$"
+}
+
+func ptrlitEscape() {
+ // Both literal and element escape.
+ i := 0 // ERROR "moved to heap: i$"
+ x := &Lit{&i} // ERROR "&Lit literal escapes to heap$" "&i escapes to heap$"
+ sink = x // ERROR "x escapes to heap$"
+}
+
+// self-assignments
+
+type Buffer struct {
+ arr [64]byte
+ buf1 []byte
+ buf2 []byte
+ str1 string
+ str2 string
+}
+
+func (b *Buffer) foo() { // ERROR "\(\*Buffer\).foo b does not escape$"
+ b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
+ b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
+ b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
+ b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
+}
+
+func (b *Buffer) bar() { // ERROR "leaking param: b$"
+ b.buf1 = b.arr[1:2] // ERROR "b.arr escapes to heap$"
+}
+
+func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
+ b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$"
+ b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$"
+}
+
+func (b *Buffer) bat() { // ERROR "leaking param content: b$"
+ o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
+ o.buf1 = b.buf1[1:2]
+ sink = o // ERROR "o escapes to heap$"
+}
+
+func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
+ *sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment to \*sp$"
+ *bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment to \*bp$"
+}
+
+type StructWithString struct {
+ p *int
+ s string
+}
+
+// This is escape analysis false negative.
+// We assign the pointer to x.p but leak x.s. Escape analysis coarsens flows
+// to just x, and thus &i looks escaping.
+func fieldFlowTracking() {
+ var x StructWithString
+ i := 0 // ERROR "moved to heap: i$"
+ x.p = &i // ERROR "&i escapes to heap$"
+ sink = x.s // ERROR "x.s escapes to heap$"
+}
+
+// String operations.
+
+func slicebytetostring0() {
+ b := make([]byte, 20) // ERROR "slicebytetostring0 make\(\[\]byte, 20\) does not escape$"
+ s := string(b) // ERROR "slicebytetostring0 string\(b\) does not escape$"
+ _ = s
+}
+
+func slicebytetostring1() {
+ b := make([]byte, 20) // ERROR "slicebytetostring1 make\(\[\]byte, 20\) does not escape$"
+ s := string(b) // ERROR "slicebytetostring1 string\(b\) does not escape$"
+ s1 := s[0:1]
+ _ = s1
+}
+
+func slicebytetostring2() {
+ b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$"
+ s := string(b) // ERROR "string\(b\) escapes to heap$"
+ s1 := s[0:1] // ERROR "moved to heap: s1$"
+ sink = &s1 // ERROR "&s1 escapes to heap$"
+}
+
+func slicebytetostring3() {
+ b := make([]byte, 20) // ERROR "slicebytetostring3 make\(\[\]byte, 20\) does not escape$"
+ s := string(b) // ERROR "string\(b\) escapes to heap$"
+ s1 := s[0:1]
+ sink = s1 // ERROR "s1 escapes to heap$"
+}
+
+func addstr0() {
+ s0 := "a"
+ s1 := "b"
+ s := s0 + s1 // ERROR "addstr0 s0 \+ s1 does not escape$"
+ _ = s
+}
+
+func addstr1() {
+ s0 := "a"
+ s1 := "b"
+ s := "c"
+ s += s0 + s1 // ERROR "addstr1 s0 \+ s1 does not escape$"
+ _ = s
+}
+
+func addstr2() {
+ b := make([]byte, 20) // ERROR "addstr2 make\(\[\]byte, 20\) does not escape$"
+ s0 := "a"
+ s := string(b) + s0 // ERROR "addstr2 string\(b\) \+ s0 does not escape$" "addstr2 string\(b\) does not escape$"
+ _ = s
+}
+
+func addstr3() {
+ s0 := "a"
+ s1 := "b"
+ s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$"
+ s2 := s[0:1]
+ sink = s2 // ERROR "s2 escapes to heap$"
+}
+
+func intstring0() bool {
+ // string does not escape
+ x := '0'
+ s := string(x) // ERROR "intstring0 string\(x\) does not escape$"
+ return s == "0"
+}
+
+func intstring1() string {
+ // string does not escape, but the buffer does
+ x := '0'
+ s := string(x) // ERROR "string\(x\) escapes to heap$"
+ return s
+}
+
+func intstring2() {
+ // string escapes to heap
+ x := '0'
+ s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
+ sink = &s // ERROR "&s escapes to heap$"
+}
+
+func stringtoslicebyte0() {
+ s := "foo"
+ x := []byte(s) // ERROR "stringtoslicebyte0 \(\[\]byte\)\(s\) does not escape$"
+ _ = x
+}
+
+func stringtoslicebyte1() []byte {
+ s := "foo"
+ return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
+}
+
+func stringtoslicebyte2() {
+ s := "foo"
+ sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
+}
+
+func stringtoslicerune0() {
+ s := "foo"
+ x := []rune(s) // ERROR "stringtoslicerune0 \(\[\]rune\)\(s\) does not escape$"
+ _ = x
+}
+
+func stringtoslicerune1() []rune {
+ s := "foo"
+ return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
+}
+
+func stringtoslicerune2() {
+ s := "foo"
+ sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
+}
+
+func slicerunetostring0() {
+ r := []rune{1, 2, 3} // ERROR "slicerunetostring0 \[\]rune literal does not escape$"
+ s := string(r) // ERROR "slicerunetostring0 string\(r\) does not escape$"
+ _ = s
+}
+
+func slicerunetostring1() string {
+ r := []rune{1, 2, 3} // ERROR "slicerunetostring1 \[\]rune literal does not escape$"
+ return string(r) // ERROR "string\(r\) escapes to heap$"
+}
+
+func slicerunetostring2() {
+ r := []rune{1, 2, 3} // ERROR "slicerunetostring2 \[\]rune literal does not escape$"
+ sink = string(r) // ERROR "string\(r\) escapes to heap$"
+}
+
+func makemap0() {
+ m := make(map[int]int) // ERROR "makemap0 make\(map\[int\]int\) does not escape$"
+ m[0] = 0
+ m[1]++
+ delete(m, 1)
+ sink = m[0] // ERROR "m\[0\] escapes to heap$"
+}
+
+func makemap1() map[int]int {
+ return make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
+}
+
+func makemap2() {
+ m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
+ sink = m // ERROR "m escapes to heap$"
+}
+
+func nonescapingEface(m map[interface{}]bool) bool { // ERROR "nonescapingEface m does not escape$"
+ return m["foo"] // ERROR "nonescapingEface .foo. does not escape$"
+}
+
+func nonescapingIface(m map[M]bool) bool { // ERROR "nonescapingIface m does not escape$"
+ return m[MV(0)] // ERROR "nonescapingIface MV\(0\) does not escape$"
+}
+
+func issue10353() {
+ x := new(int) // ERROR "new\(int\) escapes to heap$"
+ issue10353a(x)()
+}
+
+func issue10353a(x *int) func() { // ERROR "leaking param: x to result ~r1 level=-1$"
+ return func() { // ERROR "func literal escapes to heap$"
+ println(*x)
+ }
+}
+
+func issue10353b() {
+ var f func()
+ for {
+ x := new(int) // ERROR "new\(int\) escapes to heap$"
+ f = func() { // ERROR "func literal escapes to heap$"
+ println(*x)
+ }
+ }
+ _ = f
+}
+
+func issue11387(x int) func() int {
+ f := func() int { return x } // ERROR "func literal escapes to heap"
+ slice1 := []func() int{f} // ERROR "\[\].* does not escape"
+ slice2 := make([]func() int, 1) // ERROR "make\(.*\) does not escape"
+ copy(slice2, slice1)
+ return slice2[0]
+}