diff --git a/test/escape2.go b/test/escape2.go index 6b25e68616..dbb2292943 100644 --- a/test/escape2.go +++ b/test/escape2.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$" "leaking param: yy to result ~r2$" 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: 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$" + 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$" + 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 "\(\*Bar\).AlsoNoLeak leaking param b content to result ~r0$" return b.ii } -func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b" +func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0$" 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$" + 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 "\(\*Bar\).LeaksABit leaking param b content to result ~r0$" + 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,105 +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$" + 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 "\(\*Bar2\).AlsoNoLeak leaking param b content to result ~r0$" 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 - return func() int { // ERROR "func literal escapes to heap" + 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" + 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 { - return func() int { // ERROR "func literal escapes to heap" + return func() int { // ERROR "func literal escapes to heap$" return x } } func foo23a(x int) func() int { - f := func() int { // ERROR "func literal escapes to heap" + f := func() int { // ERROR "func literal escapes to heap$" return x } return f } func foo23b(x int) *(func() int) { - f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" - return &f // ERROR "&f escapes to heap" + 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" +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 { @@ -282,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: 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$" + 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$" + 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$" 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$" 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$" switch j := i; *j + 110 { case 12: return j @@ -401,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$" 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$" type S struct { a, b *int } @@ -423,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 } @@ -435,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 } @@ -448,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() } @@ -465,56 +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) // ERROR "mv does not escape" + foo63(mv) // ERROR "foo67 mv does not escape$" } func foo68() { var mv MV // escapes but it's an int so irrelevant - foo64(mv) // ERROR "mv escapes to heap" + 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 // ERROR "mv1 escapes to heap" +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 } @@ -522,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 } @@ -531,42 +531,42 @@ 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" + defer func() { // ERROR "func literal escapes to heap$" println(vv) }() } } func foo731() { - s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" + 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" - vv = 42 // 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 // actually just escapes its scope - fn := func() { // ERROR "func literal escapes to heap" + fn := func() { // ERROR "func literal escapes to heap$" println(vv) } defer fn() @@ -574,12 +574,12 @@ func foo74() { } func foo74a() { - s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" + s := []int{3, 2, 1} // ERROR "foo74a \[\]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 - fn := func() { // ERROR "func literal escapes to heap" - vv += 1 // ERROR "&vv escapes to heap" + fn := func() { // ERROR "func literal escapes to heap$" + vv += 1 // ERROR "&vv escapes to heap$" println(vv) } defer fn() @@ -589,11 +589,11 @@ func foo74a() { // 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 // actually just escapes its scope - array[i] = func() { // ERROR "func literal escapes to heap" + array[i] = func() { // ERROR "func literal escapes to heap$" println(vv) } } @@ -601,130 +601,130 @@ func foo74b() { func foo74c() { var array [3]func() - s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" + s := []int{3, 2, 1} // ERROR "foo74c \[\]int literal does not escape$" for i, v := range s { - vv := v // ERROR "moved to heap: vv" + 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" "&vv does not escape" + array[i] = func() { // ERROR "func literal escapes to heap$" + println(&vv) // ERROR "&vv escapes to heap$" " &vv does not escape$" } } } -func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y to result ~r2" +func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2$" "myprint x does not escape$" return y } -func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x to result ~r2" - return &x[0] // ERROR "&x.0. escapes to heap" +func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2$" "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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" +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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" +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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" +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" "1 escapes to heap" "2 escapes to heap" "3 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 "z does not escape" - sink = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" "myprint1\(z, 1, 2, 3\) 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$" } // BAD: z does not escape here -func foo76(z *int) { // ERROR "leaking param: z" - myprint(nil, z) // ERROR "[.][.][.] argument does not escape" "z escapes to heap" +func foo76(z *int) { // ERROR "leaking param: z$" + myprint(nil, z) // ERROR "foo76 ... argument does not escape$" "z escapes to heap$" } // BAD: z does not escape here -func foo76a(z *int) { // ERROR "leaking param: z" - myprint1(nil, z) // ERROR "[.][.][.] argument does not escape" "z escapes to heap" +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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" + 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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" + 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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" + 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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" + 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" "1 escapes to heap" "2 escapes to heap" "3 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" "1 escapes to heap" "2 escapes to heap" "3 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 foo77c(z []interface{}) { // ERROR "leaking param: z" - sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z\.\.\.\) escapes to heap" +func foo77c(z []interface{}) { // ERROR "leaking param: z$" + sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z...\) escapes to heap$" } func dotdotdot() { // BAD: i should not escape here - i := 0 // ERROR "moved to heap: i" - myprint(nil, &i) // ERROR "&i escapes to heap" "\.\.\. argument does not escape" + 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" "\.\.\. argument does not escape" + 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 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 "&y does not escape" +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 @@ -732,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$" "leaking param: p to result y$" -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$" } } @@ -762,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$" + 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$" 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 } @@ -787,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 "foo94 m does not escape$" for k, v := range m { if b { return k @@ -798,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" +func foo96(m []*int) *int { // ERROR "foo96 m does not escape$" 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$" 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$" return m[:] } // does not leak m -func foo100(m []*int) *int { // ERROR "m does not escape" +func foo100(m []*int) *int { // ERROR "foo100 m does not escape$" for _, v := range m { return v } @@ -831,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$" for _, v := range m { return v } @@ -839,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" +func foo104(x []*int) { // ERROR "foo104 x does not escape$" copy(y, x) } // does not leak x -func foo105(x []*int) { // ERROR "x does not escape" +func foo105(x []*int) { // ERROR "foo105 x does not escape$" _ = 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$" + 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$" 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$" 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$" + 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$" 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) } @@ -1152,16 +1152,16 @@ L100: func foo121() { for i := 0; i < 10; i++ { - 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" + 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" "i escapes to heap" - go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap" "i 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$" } } @@ -1171,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 } @@ -1180,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$" }() } @@ -1206,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 @@ -1217,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 " func literal does not escape$" + r := q // ERROR "leaking closure reference q$" px = r }() }() @@ -1244,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 " func literal does not escape$" r := q _ = r }() @@ -1285,11 +1285,11 @@ func foo134() { } func foo135() { - var i int // ERROR "moved to heap: i" - p := &i // ERROR "&i escapes to heap" - go func() { // ERROR "func literal escapes to heap" + 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 "func literal does not escape" + func() { // ERROR " func literal does not escape$" r := q _ = r }() @@ -1297,23 +1297,23 @@ func foo135() { } func foo136() { - 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 "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 " 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" - go func() { // ERROR "func literal 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 }() @@ -1324,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 { @@ -1334,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 @@ -1347,8 +1347,8 @@ func foo140() interface{} { X string T *T } - t := &T{} // ERROR "&T literal escapes to heap" - return U{ // ERROR "U literal escapes to heap" + t := &T{} // ERROR "&T literal escapes to heap$" + return U{ // ERROR "U literal escapes to heap$" X: t.X, T: t, } @@ -1362,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 " t does not escape$" } }() } @@ -1424,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 @@ -1439,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$" } } } @@ -1479,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 @@ -1525,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 "\(\*U\).String leaking param u content to result ~r0$" return u.s } @@ -1533,36 +1533,36 @@ 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" +func NewV(u U) *V { // ERROR "leaking param: u$" + 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$" 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 } @@ -1575,22 +1575,22 @@ type Lit struct { func ptrlitNoescape() { // Both literal and element do not escape. i := 0 - x := &Lit{&i} // ERROR "&Lit literal does not escape" "&i does not escape" + 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 "&Lit literal does not escape" "&i escapes to heap" - sink = *x // ERROR "\*x escapes to heap" + 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" + 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 @@ -1603,31 +1603,31 @@ type Buffer struct { str2 string } -func (b *Buffer) foo() { // ERROR "b does not escape" - b.buf1 = b.buf1[1:2] // ERROR "ignoring self-assignment to b.buf1" - b.buf1 = b.buf1[1:2:3] // ERROR "ignoring self-assignment to b.buf1" - b.buf1 = b.buf2[1:2] // ERROR "ignoring self-assignment to b.buf1" - b.buf1 = b.buf2[1:2:3] // ERROR "ignoring self-assignment to b.buf1" +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) bar() { // ERROR "leaking param: b$" + b.buf1 = b.arr[1:2] // ERROR "b.arr escapes to heap$" } -func (b *Buffer) baz() { // ERROR "b does not escape" - b.str1 = b.str1[1:2] // ERROR "ignoring self-assignment to b.str1" - b.str1 = b.str2[1:2] // ERROR "ignoring self-assignment to b.str1" +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: b" - o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap" +func (b *Buffer) bat() { // ERROR "leaking param: b$" + o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$" o.buf1 = b.buf1[1:2] - sink = o // ERROR "o escapes to heap" + sink = o // ERROR "o escapes to heap$" } -func quux(sp *string, bp *[]byte) { // ERROR "sp does not escape" "bp 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" +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 { @@ -1640,44 +1640,44 @@ type StructWithString struct { // 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" + 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 "does not escape" - s := string(b) // ERROR "string\(b\) does not escape" + 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 "does not escape" - s := string(b) // ERROR "string\(b\) does not escape" + 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 "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" + 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 "does not escape" - s := string(b) // ERROR "string\(b\) escapes to heap" + 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" + sink = s1 // ERROR "s1 escapes to heap$" } func addstr0() { s0 := "a" s1 := "b" - s := s0 + s1 // ERROR "s0 \+ s1 does not escape" + s := s0 + s1 // ERROR "addstr0 s0 \+ s1 does not escape$" _ = s } @@ -1685,126 +1685,126 @@ func addstr1() { s0 := "a" s1 := "b" s := "c" - s += s0 + s1 // ERROR "s0 \+ s1 does not escape" + s += s0 + s1 // ERROR "addstr1 s0 \+ s1 does not escape$" _ = s } func addstr2() { - b := make([]byte, 20) // ERROR "does not escape" + b := make([]byte, 20) // ERROR "addstr2 make\(\[\]byte, 20\) does not escape$" s0 := "a" - s := string(b) + s0 // ERROR "string\(b\) does not escape" "string\(b\) \+ s0 does not escape" + 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" + s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$" s2 := s[0:1] - sink = s2 // ERROR "s2 escapes to heap" + sink = s2 // ERROR "s2 escapes to heap$" } func intstring0() bool { // string does not escape x := '0' - s := string(x) // ERROR "string\(x\) does not escape" + 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" + s := string(x) // ERROR "string\(x\) escapes to heap$" return s } func intstring2() { // string escapes to heap x := '0' - s := string(x) // ERROR "string\(x\) escapes to heap" "moved to heap: s" - sink = &s // ERROR "&s escapes to heap" + 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 "\(\[\]byte\)\(s\) does not escape" + 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" + return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$" } func stringtoslicebyte2() { s := "foo" - sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap" + sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$" } func stringtoslicerune0() { s := "foo" - x := []rune(s) // ERROR "\(\[\]rune\)\(s\) does not escape" + 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" + return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$" } func stringtoslicerune2() { s := "foo" - sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap" + sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$" } func slicerunetostring0() { - r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape" - s := string(r) // ERROR "string\(r\) does not escape" + 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 "\[\]rune literal does not escape" - return string(r) // ERROR "string\(r\) escapes to heap" + 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 "\[\]rune literal does not escape" - sink = string(r) // ERROR "string\(r\) escapes to heap" + 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 "make\(map\[int\]int\) does not escape" + 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" + 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" + 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" + 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 "m does not escape" - return m["foo"] // ERROR `"foo" does not escape` +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 "m does not escape" - return m[MV(0)] // ERROR "MV\(0\) 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" + x := new(int) // ERROR "new\(int\) escapes to heap$" issue10353a(x)() } -func issue10353a(x *int) func() { // ERROR "leaking param: x" - return func() { // ERROR "func literal escapes to heap" +func issue10353a(x *int) func() { // ERROR "leaking param: x$" + return func() { // ERROR "func literal escapes to heap$" println(*x) } } @@ -1812,8 +1812,8 @@ func issue10353a(x *int) func() { // ERROR "leaking param: x" func issue10353b() { var f func() for { - x := new(int) // ERROR "new\(int\) escapes to heap" - f = func() { // ERROR "func literal escapes to heap" + x := new(int) // ERROR "new\(int\) escapes to heap$" + f = func() { // ERROR "func literal escapes to heap$" println(*x) } } diff --git a/test/escape2n.go b/test/escape2n.go index fff1f95958..a414addc73 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$" "leaking param: yy to result ~r2$" 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: 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$" + 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$" + 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 "\(\*Bar\).AlsoNoLeak leaking param b content to result ~r0$" return b.ii } -func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b" +func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0$" 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$" + 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 "\(\*Bar\).LeaksABit leaking param b content to result ~r0$" + 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,105 +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$" + 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 "\(\*Bar2\).AlsoNoLeak leaking param b content to result ~r0$" 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 - return func() int { // ERROR "func literal escapes to heap" + 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" + 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 { - return func() int { // ERROR "func literal escapes to heap" + return func() int { // ERROR "func literal escapes to heap$" return x } } func foo23a(x int) func() int { - f := func() int { // ERROR "func literal escapes to heap" + f := func() int { // ERROR "func literal escapes to heap$" return x } return f } func foo23b(x int) *(func() int) { - f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" - return &f // ERROR "&f escapes to heap" + 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" +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 { @@ -282,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: 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$" + 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$" + 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$" 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$" 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$" switch j := i; *j + 110 { case 12: return j @@ -401,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$" 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$" type S struct { a, b *int } @@ -423,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 } @@ -435,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 } @@ -448,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() } @@ -465,56 +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) // ERROR "mv does not escape" + foo63(mv) // ERROR "foo67 mv does not escape$" } func foo68() { var mv MV // escapes but it's an int so irrelevant - foo64(mv) // ERROR "mv escapes to heap" + 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 // ERROR "mv1 escapes to heap" +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 } @@ -522,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 } @@ -531,42 +531,42 @@ 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" + defer func() { // ERROR "func literal escapes to heap$" println(vv) }() } } func foo731() { - s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" + 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" - vv = 42 // 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 // actually just escapes its scope - fn := func() { // ERROR "func literal escapes to heap" + fn := func() { // ERROR "func literal escapes to heap$" println(vv) } defer fn() @@ -574,12 +574,12 @@ func foo74() { } func foo74a() { - s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" + s := []int{3, 2, 1} // ERROR "foo74a \[\]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 - fn := func() { // ERROR "func literal escapes to heap" - vv += 1 // ERROR "&vv escapes to heap" + fn := func() { // ERROR "func literal escapes to heap$" + vv += 1 // ERROR "&vv escapes to heap$" println(vv) } defer fn() @@ -589,11 +589,11 @@ func foo74a() { // 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 // actually just escapes its scope - array[i] = func() { // ERROR "func literal escapes to heap" + array[i] = func() { // ERROR "func literal escapes to heap$" println(vv) } } @@ -601,130 +601,130 @@ func foo74b() { func foo74c() { var array [3]func() - s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape" + s := []int{3, 2, 1} // ERROR "foo74c \[\]int literal does not escape$" for i, v := range s { - vv := v // ERROR "moved to heap: vv" + 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" "&vv does not escape" + array[i] = func() { // ERROR "func literal escapes to heap$" + println(&vv) // ERROR "&vv escapes to heap$" " &vv does not escape$" } } } -func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y to result ~r2" +func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2$" "myprint x does not escape$" return y } -func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x to result ~r2" - return &x[0] // ERROR "&x.0. escapes to heap" +func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2$" "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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" +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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" +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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" +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" "1 escapes to heap" "2 escapes to heap" "3 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 "z does not escape" - sink = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" "myprint1\(z, 1, 2, 3\) 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$" } // BAD: z does not escape here -func foo76(z *int) { // ERROR "leaking param: z" - myprint(nil, z) // ERROR "[.][.][.] argument does not escape" "z escapes to heap" +func foo76(z *int) { // ERROR "leaking param: z$" + myprint(nil, z) // ERROR "foo76 ... argument does not escape$" "z escapes to heap$" } // BAD: z does not escape here -func foo76a(z *int) { // ERROR "leaking param: z" - myprint1(nil, z) // ERROR "[.][.][.] argument does not escape" "z escapes to heap" +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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" + 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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" + 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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" + 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" "1 escapes to heap" "2 escapes to heap" "3 escapes to heap" + 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" "1 escapes to heap" "2 escapes to heap" "3 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" "1 escapes to heap" "2 escapes to heap" "3 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 foo77c(z []interface{}) { // ERROR "leaking param: z" - sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z\.\.\.\) escapes to heap" +func foo77c(z []interface{}) { // ERROR "leaking param: z$" + sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z...\) escapes to heap$" } func dotdotdot() { // BAD: i should not escape here - i := 0 // ERROR "moved to heap: i" - myprint(nil, &i) // ERROR "&i escapes to heap" "\.\.\. argument does not escape" + 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" "\.\.\. argument does not escape" + 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 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 "&y does not escape" +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 @@ -732,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$" "leaking param: p to result y$" -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$" } } @@ -762,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$" + 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$" 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 } @@ -787,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 "foo94 m does not escape$" for k, v := range m { if b { return k @@ -798,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" +func foo96(m []*int) *int { // ERROR "foo96 m does not escape$" 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$" 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$" return m[:] } // does not leak m -func foo100(m []*int) *int { // ERROR "m does not escape" +func foo100(m []*int) *int { // ERROR "foo100 m does not escape$" for _, v := range m { return v } @@ -831,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$" for _, v := range m { return v } @@ -839,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" +func foo104(x []*int) { // ERROR "foo104 x does not escape$" copy(y, x) } // does not leak x -func foo105(x []*int) { // ERROR "x does not escape" +func foo105(x []*int) { // ERROR "foo105 x does not escape$" _ = 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$" + 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$" 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$" 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$" + 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$" 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) } @@ -1152,16 +1152,16 @@ L100: func foo121() { for i := 0; i < 10; i++ { - 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" + 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" "i escapes to heap" - go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap" "i 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$" } } @@ -1171,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 } @@ -1180,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$" }() } @@ -1206,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 @@ -1217,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 " func literal does not escape$" + r := q // ERROR "leaking closure reference q$" px = r }() }() @@ -1244,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 " func literal does not escape$" r := q _ = r }() @@ -1285,11 +1285,11 @@ func foo134() { } func foo135() { - var i int // ERROR "moved to heap: i" - p := &i // ERROR "&i escapes to heap" - go func() { // ERROR "func literal escapes to heap" + 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 "func literal does not escape" + func() { // ERROR " func literal does not escape$" r := q _ = r }() @@ -1297,23 +1297,23 @@ func foo135() { } func foo136() { - 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 "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 " 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" - go func() { // ERROR "func literal 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 }() @@ -1324,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 { @@ -1334,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 @@ -1347,8 +1347,8 @@ func foo140() interface{} { X string T *T } - t := &T{} // ERROR "&T literal escapes to heap" - return U{ // ERROR "U literal escapes to heap" + t := &T{} // ERROR "&T literal escapes to heap$" + return U{ // ERROR "U literal escapes to heap$" X: t.X, T: t, } @@ -1362,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 " t does not escape$" } }() } @@ -1424,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 @@ -1439,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$" } } } @@ -1479,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 @@ -1525,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 "\(\*U\).String leaking param u content to result ~r0$" return u.s } @@ -1533,36 +1533,36 @@ 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" +func NewV(u U) *V { // ERROR "leaking param: u$" + 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$" 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 } @@ -1575,22 +1575,22 @@ type Lit struct { func ptrlitNoescape() { // Both literal and element do not escape. i := 0 - x := &Lit{&i} // ERROR "&Lit literal does not escape" "&i does not escape" + 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 "&Lit literal does not escape" "&i escapes to heap" - sink = *x // ERROR "\*x escapes to heap" + 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" + 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 @@ -1603,31 +1603,31 @@ type Buffer struct { str2 string } -func (b *Buffer) foo() { // ERROR "b does not escape" - b.buf1 = b.buf1[1:2] // ERROR "ignoring self-assignment to b.buf1" - b.buf1 = b.buf1[1:2:3] // ERROR "ignoring self-assignment to b.buf1" - b.buf1 = b.buf2[1:2] // ERROR "ignoring self-assignment to b.buf1" - b.buf1 = b.buf2[1:2:3] // ERROR "ignoring self-assignment to b.buf1" +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) bar() { // ERROR "leaking param: b$" + b.buf1 = b.arr[1:2] // ERROR "b.arr escapes to heap$" } -func (b *Buffer) baz() { // ERROR "b does not escape" - b.str1 = b.str1[1:2] // ERROR "ignoring self-assignment to b.str1" - b.str1 = b.str2[1:2] // ERROR "ignoring self-assignment to b.str1" +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: b" - o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap" +func (b *Buffer) bat() { // ERROR "leaking param: b$" + o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$" o.buf1 = b.buf1[1:2] - sink = o // ERROR "o escapes to heap" + sink = o // ERROR "o escapes to heap$" } -func quux(sp *string, bp *[]byte) { // ERROR "sp does not escape" "bp 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" +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 { @@ -1640,44 +1640,44 @@ type StructWithString struct { // 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" + 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 "does not escape" - s := string(b) // ERROR "string\(b\) does not escape" + 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 "does not escape" - s := string(b) // ERROR "string\(b\) does not escape" + 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 "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" + 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 "does not escape" - s := string(b) // ERROR "string\(b\) escapes to heap" + 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" + sink = s1 // ERROR "s1 escapes to heap$" } func addstr0() { s0 := "a" s1 := "b" - s := s0 + s1 // ERROR "s0 \+ s1 does not escape" + s := s0 + s1 // ERROR "addstr0 s0 \+ s1 does not escape$" _ = s } @@ -1685,126 +1685,126 @@ func addstr1() { s0 := "a" s1 := "b" s := "c" - s += s0 + s1 // ERROR "s0 \+ s1 does not escape" + s += s0 + s1 // ERROR "addstr1 s0 \+ s1 does not escape$" _ = s } func addstr2() { - b := make([]byte, 20) // ERROR "does not escape" + b := make([]byte, 20) // ERROR "addstr2 make\(\[\]byte, 20\) does not escape$" s0 := "a" - s := string(b) + s0 // ERROR "string\(b\) does not escape" "string\(b\) \+ s0 does not escape" + 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" + s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$" s2 := s[0:1] - sink = s2 // ERROR "s2 escapes to heap" + sink = s2 // ERROR "s2 escapes to heap$" } func intstring0() bool { // string does not escape x := '0' - s := string(x) // ERROR "string\(x\) does not escape" + 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" + s := string(x) // ERROR "string\(x\) escapes to heap$" return s } func intstring2() { // string escapes to heap x := '0' - s := string(x) // ERROR "string\(x\) escapes to heap" "moved to heap: s" - sink = &s // ERROR "&s escapes to heap" + 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 "\(\[\]byte\)\(s\) does not escape" + 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" + return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$" } func stringtoslicebyte2() { s := "foo" - sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap" + sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$" } func stringtoslicerune0() { s := "foo" - x := []rune(s) // ERROR "\(\[\]rune\)\(s\) does not escape" + 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" + return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$" } func stringtoslicerune2() { s := "foo" - sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap" + sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$" } func slicerunetostring0() { - r := []rune{1, 2, 3} // ERROR "\[\]rune literal does not escape" - s := string(r) // ERROR "string\(r\) does not escape" + 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 "\[\]rune literal does not escape" - return string(r) // ERROR "string\(r\) escapes to heap" + 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 "\[\]rune literal does not escape" - sink = string(r) // ERROR "string\(r\) escapes to heap" + 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 "make\(map\[int\]int\) does not escape" + 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" + 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" + 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" + 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 "m does not escape" - return m["foo"] // ERROR `"foo" does not escape` +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 "m does not escape" - return m[MV(0)] // ERROR "MV\(0\) 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" + x := new(int) // ERROR "new\(int\) escapes to heap$" issue10353a(x)() } -func issue10353a(x *int) func() { // ERROR "leaking param: x" - return func() { // ERROR "func literal escapes to heap" +func issue10353a(x *int) func() { // ERROR "leaking param: x$" + return func() { // ERROR "func literal escapes to heap$" println(*x) } } @@ -1812,8 +1812,8 @@ func issue10353a(x *int) func() { // ERROR "leaking param: x" func issue10353b() { var f func() for { - x := new(int) // ERROR "new\(int\) escapes to heap" - f = func() { // ERROR "func literal escapes to heap" + x := new(int) // ERROR "new\(int\) escapes to heap$" + f = func() { // ERROR "func literal escapes to heap$" println(*x) } } diff --git a/test/live.go b/test/live.go index 2f421066a5..ae982f4957 100644 --- a/test/live.go +++ b/test/live.go @@ -64,7 +64,7 @@ func f3(b bool) { printpointer(&y) // ERROR "live at call to printpointer: x y$" printpointer(&y) // ERROR "live at call to printpointer: x y$" } - printint(0) // ERROR "live at call to printint: x y$" "x \(type \*int\) is ambiguously live" "y \(type \*int\) is ambiguously live" + printint(0) // ERROR "f3: x \(type \*int\) is ambiguously live$" "f3: y \(type \*int\) is ambiguously live$" "live at call to printint: x y$" } // The old algorithm treated x as live on all code that @@ -103,7 +103,7 @@ func f5(b1 bool) { *y = 54 z = &y } - printint(**z) // ERROR "live at call to printint: x y$" "x \(type \*int\) is ambiguously live" "y \(type \*int\) is ambiguously live" + printint(**z) // ERROR "f5: x \(type \*int\) is ambiguously live$" "f5: y \(type \*int\) is ambiguously live$" "live at call to printint: x y$" } // confusion about the _ result used to cause spurious "live at entry to f6: _". @@ -137,7 +137,7 @@ var i9 interface{} func f9() bool { g8() x := i9 - return x != interface{}(99.0i) // ERROR "live at call to convT2E: x" + return x != interface{}(99.0i) // ERROR "live at call to convT2E: x$" } // liveness formerly confused by UNDEF followed by RET, @@ -157,10 +157,10 @@ var b bool // this used to have a spurious "live at entry to f11a: ~r0" func f11a() *int { - select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp" - case <-c: // ERROR "live at call to selectrecv: autotmp" + select { // ERROR "live at call to newselect: autotmp_[0-9]+$" "live at call to selectgo: autotmp_[0-9]+$" + case <-c: // ERROR "live at call to selectrecv: autotmp_[0-9]+$" return nil - case <-c: // ERROR "live at call to selectrecv: autotmp" + case <-c: // ERROR "live at call to selectrecv: autotmp_[0-9]+$" return nil } } @@ -172,10 +172,10 @@ func f11b() *int { // get to the bottom of the function. // This used to have a spurious "live at call to printint: p". printint(1) // nothing live here! - select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp" - case <-c: // ERROR "live at call to selectrecv: autotmp" + select { // ERROR "live at call to newselect: autotmp_[0-9]+$" "live at call to selectgo: autotmp_[0-9]+$" + case <-c: // ERROR "live at call to selectrecv: autotmp_[0-9]+$" return nil - case <-c: // ERROR "live at call to selectrecv: autotmp" + case <-c: // ERROR "live at call to selectrecv: autotmp_[0-9]+$" return nil } } @@ -188,10 +188,10 @@ func f11c() *int { if b { // Unlike previous, the cases in this select fall through, // so we can get to the println, so p is not dead. - printint(1) // ERROR "live at call to printint: p" - select { // ERROR "live at call to newselect: autotmp.* p" "live at call to selectgo: autotmp.* p" - case <-c: // ERROR "live at call to selectrecv: autotmp.* p" - case <-c: // ERROR "live at call to selectrecv: autotmp.* p" + printint(1) // ERROR "live at call to printint: p$" + select { // ERROR "live at call to newselect: autotmp_[0-9]+ p$" "live at call to selectgo: autotmp_[0-9]+ p$" + case <-c: // ERROR "live at call to selectrecv: autotmp_[0-9]+ p$" + case <-c: // ERROR "live at call to selectrecv: autotmp_[0-9]+ p$" } } println(*p) @@ -215,7 +215,7 @@ func f12() *int { func f13() { s := "hello" - s = h13(s, g13(s)) // ERROR "live at call to g13: s" + s = h13(s, g13(s)) // ERROR "live at call to g13: s$" } func g13(string) string @@ -225,7 +225,7 @@ func h13(string, string) string func f14() { x := g14() - printstringpointer(&x) // ERROR "live at call to printstringpointer: x" + printstringpointer(&x) // ERROR "live at call to printstringpointer: x$" } func g14() string @@ -233,8 +233,8 @@ func g14() string func f15() { var x string _ = &x - x = g15() // ERROR "live at call to g15: x" - printstring(x) // ERROR "live at call to printstring: x" + x = g15() // ERROR "live at call to g15: x$" + printstring(x) // ERROR "live at call to printstring: x$" } func g15() string @@ -367,9 +367,9 @@ func f25(b bool) { } var x string _ = &x - x = g15() // ERROR "live at call to g15: x" - printstring(x) // ERROR "live at call to printstring: x" -} // ERROR "live at call to deferreturn: x" + x = g15() // ERROR "live at call to g15: x$" + printstring(x) // ERROR "live at call to printstring: x$" +} // ERROR "live at call to deferreturn: x$" func g25() @@ -408,7 +408,7 @@ func f27defer(b bool) { if b { defer call27(func() { x++ }) // ERROR "live at call to deferproc: autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+$" } - defer call27(func() { x++ }) // ERROR "live at call to deferproc: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$" "ambiguously live" + defer call27(func() { x++ }) // ERROR "f27defer: autotmp_[0-9]+ \(type struct { F uintptr; x \*int }\) is ambiguously live$" "live at call to deferproc: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$" printnl() // ERROR "live at call to printnl: autotmp_[0-9]+ autotmp_[0-9]+$" } // ERROR "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$" @@ -417,9 +417,9 @@ func f27defer(b bool) { func f27go(b bool) { x := 0 if b { - go call27(func() { x++ }) // ERROR "live at call to newobject: &x" "live at call to newproc: &x$" + go call27(func() { x++ }) // ERROR "live at call to newobject: &x$" "live at call to newproc: &x$" } - go call27(func() { x++ }) // ERROR "live at call to newobject: &x" + go call27(func() { x++ }) // ERROR "live at call to newobject: &x$" printnl() } @@ -481,7 +481,7 @@ func f31(b1, b2, b3 bool) { g31("a") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to g31: autotmp_[0-9]+$" } if b2 { - h31("b") // ERROR "live at call to newobject: autotmp_[0-9]+$" "live at call to convT2E: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to h31: autotmp_[0-9]+$" + h31("b") // ERROR "live at call to convT2E: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to h31: autotmp_[0-9]+$" "live at call to newobject: autotmp_[0-9]+$" } if b3 { panic("asdf") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to gopanic: autotmp_[0-9]+$" @@ -496,7 +496,7 @@ func h31(...interface{}) type T32 int -func (t *T32) Inc() { // ERROR "live at entry" +func (t *T32) Inc() { // ERROR "live at entry to \(\*T32\).Inc: t$" *t++ } @@ -573,14 +573,14 @@ func f38(b bool) { // we care that the println lines have no live variables // and therefore no output. if b { - select { // ERROR "live at call" - case <-fc38(): // ERROR "live at call" + select { // ERROR "live at call to newselect: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to selectgo: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" + case <-fc38(): // ERROR "live at call to selectrecv: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" printnl() - case fc38() <- *fi38(1): // ERROR "live at call" + case fc38() <- *fi38(1): // ERROR "live at call to fc38: autotmp_[0-9]+$" "live at call to fi38: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to selectsend: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" printnl() - case *fi38(2) = <-fc38(): // ERROR "live at call" + case *fi38(2) = <-fc38(): // ERROR "live at call to fc38: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to fi38: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to selectrecv: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" printnl() - case *fi38(3), *fb38() = <-fc38(): // ERROR "live at call" + case *fi38(3), *fb38() = <-fc38(): // ERROR "live at call to fb38: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to fc38: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to fi38: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to selectrecv2: autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+ autotmp_[0-9]+$" printnl() } printnl() @@ -592,27 +592,27 @@ func f38(b bool) { func f39() (x []int) { x = []int{1} - printnl() // ERROR "live at call to printnl: x" + printnl() // ERROR "live at call to printnl: x$" return x } func f39a() (x []int) { x = []int{1} - printnl() // ERROR "live at call to printnl: x" + printnl() // ERROR "live at call to printnl: x$" return } func f39b() (x [10]*int) { x = [10]*int{} - x[0] = new(int) // ERROR "live at call to newobject: x" - printnl() // ERROR "live at call to printnl: x" + x[0] = new(int) // ERROR "live at call to newobject: x$" + printnl() // ERROR "live at call to printnl: x$" return x } func f39c() (x [10]*int) { x = [10]*int{} - x[0] = new(int) // ERROR "live at call to newobject: x" - printnl() // ERROR "live at call to printnl: x" + x[0] = new(int) // ERROR "live at call to newobject: x$" + printnl() // ERROR "live at call to printnl: x$" return } @@ -625,7 +625,7 @@ type T40 struct { func newT40() *T40 { ret := T40{} - ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret" + ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret$" return &ret } @@ -637,8 +637,8 @@ func bad40() { func good40() { ret := T40{} - ret.m = make(map[int]int) // ERROR "live at call to makemap: autotmp_.* ret" + ret.m = make(map[int]int) // ERROR "live at call to makemap: autotmp_[0-9]+ ret$" t := &ret - printnl() // ERROR "live at call to printnl: autotmp_.* ret" + printnl() // ERROR "live at call to printnl: autotmp_[0-9]+ ret$" _ = t } diff --git a/test/run.go b/test/run.go index bcd89a031f..75eccb1dfd 100644 --- a/test/run.go +++ b/test/run.go @@ -36,6 +36,7 @@ var ( numParallel = flag.Int("n", runtime.NumCPU(), "number of parallel tests to run") summary = flag.Bool("summary", false, "show summary of results") showSkips = flag.Bool("show_skips", false, "show skipped tests") + updateErrors = flag.Bool("update_errors", false, "update error messages in test file based on compiler output") runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run") ) @@ -521,6 +522,9 @@ func (t *test) run() { return } } + if *updateErrors { + t.updateErrors(string(out), long) + } t.err = t.errorCheck(string(out), long, t.gofile) return @@ -721,6 +725,25 @@ func (t *test) expectedOutput() string { return string(b) } +func splitOutput(out string) []string { + // 6g error messages continue onto additional lines with leading tabs. + // Split the output at the beginning of each line that doesn't begin with a tab. + var res []string + for _, line := range strings.Split(out, "\n") { + if strings.HasSuffix(line, "\r") { // remove '\r', output by compiler on windows + line = line[:len(line)-1] + } + if strings.HasPrefix(line, "\t") { + res[len(res)-1] += "\n" + line + } else if strings.HasPrefix(line, "go tool") { + continue + } else if strings.TrimSpace(line) != "" { + res = append(res, line) + } + } + return res +} + func (t *test) errorCheck(outStr string, fullshort ...string) (err error) { defer func() { if *verbose && err != nil { @@ -728,22 +751,7 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) { } }() var errs []error - - var out []string - // 6g error messages continue onto additional lines with leading tabs. - // Split the output at the beginning of each line that doesn't begin with a tab. - for _, line := range strings.Split(outStr, "\n") { - if strings.HasSuffix(line, "\r") { // remove '\r', output by compiler on windows - line = line[:len(line)-1] - } - if strings.HasPrefix(line, "\t") { - out[len(out)-1] += "\n" + line - } else if strings.HasPrefix(line, "go tool") { - continue - } else if strings.TrimSpace(line) != "" { - out = append(out, line) - } - } + out := splitOutput(outStr) // Cut directory name. for i := range out { @@ -800,7 +808,72 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) { fmt.Fprintf(&buf, "%s\n", err.Error()) } return errors.New(buf.String()) +} +func (t *test) updateErrors(out string, file string) { + // Read in source file. + src, err := ioutil.ReadFile(file) + if err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + lines := strings.Split(string(src), "\n") + // Remove old errors. + for i, ln := range lines { + pos := strings.Index(ln, " // ERROR ") + if pos >= 0 { + lines[i] = ln[:pos] + } + } + // Parse new errors. + errors := make(map[int]map[string]bool) + tmpRe := regexp.MustCompile(`autotmp_[0-9]+`) + for _, errStr := range splitOutput(out) { + colon1 := strings.Index(errStr, ":") + if colon1 < 0 || errStr[:colon1] != file{ + continue + } + colon2 := strings.Index(errStr[colon1+1:], ":") + if colon2 < 0 { + continue + } + colon2 += colon1+1 + line, err := strconv.Atoi(errStr[colon1+1:colon2]) + line-- + if err != nil || line < 0 || line >= len(lines) { + continue + } + msg := errStr[colon2+2:] + for _, r := range []string{`\`, `*`, `+`, `[`, `]`, `(`, `)`} { + msg = strings.Replace(msg, r, `\` + r, -1) + } + msg = strings.Replace(msg, `"`, `.`, -1) + msg = tmpRe.ReplaceAllLiteralString(msg, `autotmp_[0-9]+`) + if errors[line] == nil { + errors[line] = make(map[string]bool) + } + errors[line][msg] = true + } + // Add new errors. + for line, errs := range errors { + var sorted []string + for e := range errs { + sorted = append(sorted, e) + } + sort.Strings(sorted) + lines[line] += " // ERROR" + for _, e := range sorted { + lines[line] += fmt.Sprintf(` "%s$"`, e) + } + } + // Write new file. + err = ioutil.WriteFile(file, []byte(strings.Join(lines, "\n")), 0640) + if err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + // Polish. + exec.Command("go", "fmt", file).CombinedOutput() } // matchPrefix reports whether s is of the form ^(.*/)?prefix(:|[), @@ -884,7 +957,7 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) { var err error re, err = regexp.Compile(rx) if err != nil { - log.Fatalf("%s:%d: invalid regexp in ERROR line: %v", t.goFileName(), lineNum, err) + log.Fatalf("%s:%d: invalid regexp \"%s\" in ERROR line: %v", t.goFileName(), lineNum, rx, err) } cache[rx] = re }