Commit 9f89edcd authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: silence esc diagnostics about directiface OCONVIFACEs

In general, a conversion to interface type may require values to be
boxed, which in turn necessitates escape analysis to determine whether
the boxed representation can be stack allocated.

However, esc.go used to unconditionally print escape analysis
decisions about OCONVIFACE, even for conversions that don't require
boxing (e.g., pointers, channels, maps, functions).

For test compatibility with esc.go, escape.go similarly printed these
useless diagnostics. This CL removes the diagnostics, and updates test
expectations accordingly.

Change-Id: I97c57a4a08e44d265bba516c78426ff4f2bf1e12
Reviewed-on: https://go-review.googlesource.com/c/go/+/192697
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
parent a71967e4
...@@ -484,13 +484,6 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) { ...@@ -484,13 +484,6 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
case OCONVIFACE: case OCONVIFACE:
if !n.Left.Type.IsInterface() && !isdirectiface(n.Left.Type) { if !n.Left.Type.IsInterface() && !isdirectiface(n.Left.Type) {
k = e.spill(k, n) k = e.spill(k, n)
} else {
// esc.go prints "escapes to heap" / "does not
// escape" messages for OCONVIFACE even when
// they don't allocate. Match that behavior
// because it's easy.
// TODO(mdempsky): Remove and cleanup test expectations.
_ = e.spill(k, n)
} }
e.expr(k.note(n, "interface-converted"), n.Left) e.expr(k.note(n, "interface-converted"), n.Left)
......
...@@ -146,13 +146,13 @@ func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$ ...@@ -146,13 +146,13 @@ func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$
} }
func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$" func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$"
v := 0 // ERROR "moved to heap: v$" v := 0 // ERROR "moved to heap: v$"
b.ii = &v b.ii = &v
return b.ii return b.ii
} }
func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$" func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$"
v := 0 // ERROR "moved to heap: v$" v := 0 // ERROR "moved to heap: v$"
b.ii = &v b.ii = &v
return b.ii return b.ii
} }
...@@ -465,12 +465,12 @@ func (MV) M() {} ...@@ -465,12 +465,12 @@ func (MV) M() {}
func foo65() { func foo65() {
var mv MV var mv MV
foo63(&mv) // ERROR "foo65 &mv does not escape$" foo63(&mv)
} }
func foo66() { func foo66() {
var mv MV // ERROR "moved to heap: mv$" var mv MV // ERROR "moved to heap: mv$"
foo64(&mv) // ERROR "&mv escapes to heap$" foo64(&mv)
} }
func foo67() { func foo67() {
...@@ -489,7 +489,7 @@ func foo69(m M) { // ERROR "leaking param: m$" ...@@ -489,7 +489,7 @@ func foo69(m M) { // ERROR "leaking param: m$"
} }
func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$" func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
m = mv1 // ERROR "mv1 escapes to heap$" m = mv1
foo64(m) foo64(m)
} }
...@@ -522,7 +522,7 @@ func foo72a() { ...@@ -522,7 +522,7 @@ func foo72a() {
var y [10]*int var y [10]*int
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
// escapes its scope // escapes its scope
x := i // ERROR "moved to heap: x$" x := i // ERROR "moved to heap: x$"
y[i] = &x y[i] = &x
} }
return return
...@@ -531,7 +531,7 @@ func foo72a() { ...@@ -531,7 +531,7 @@ func foo72a() {
func foo72b() [10]*int { func foo72b() [10]*int {
var y [10]*int var y [10]*int
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
x := i // ERROR "moved to heap: x$" x := i // ERROR "moved to heap: x$"
y[i] = &x y[i] = &x
} }
return y return y
...@@ -637,15 +637,15 @@ func foo75aesc(z *int) { // ERROR "foo75aesc z does not escape$" ...@@ -637,15 +637,15 @@ func foo75aesc(z *int) { // ERROR "foo75aesc z does not escape$"
} }
func foo75aesc1(z *int) { // ERROR "foo75aesc1 z does not escape$" 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$" sink = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
} }
func foo76(z *int) { // ERROR "z does not escape" func foo76(z *int) { // ERROR "z does not escape"
myprint(nil, z) // ERROR "foo76 ... argument does not escape$" "z does not escape" myprint(nil, z) // ERROR "foo76 ... argument does not escape$"
} }
func foo76a(z *int) { // ERROR "z does not escape" func foo76a(z *int) { // ERROR "z does not escape"
myprint1(nil, z) // ERROR "foo76a ... argument does not escape$" "z does not escape" myprint1(nil, z) // ERROR "foo76a ... argument does not escape$"
} }
func foo76b() { func foo76b() {
...@@ -691,15 +691,15 @@ func foo77b(z []interface{}) { // ERROR "leaking param: z$" ...@@ -691,15 +691,15 @@ func foo77b(z []interface{}) { // ERROR "leaking param: z$"
} }
func foo77c(z []interface{}) { // ERROR "leaking param: z$" func foo77c(z []interface{}) { // ERROR "leaking param: z$"
sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z...\) escapes to heap$" sink = myprint1(nil, z...)
} }
func dotdotdot() { func dotdotdot() {
i := 0 i := 0
myprint(nil, &i) // ERROR "&i does not escape" "dotdotdot ... argument does not escape$" myprint(nil, &i) // ERROR "dotdotdot ... argument does not escape$"
j := 0 j := 0
myprint1(nil, &j) // ERROR "&j does not escape" "dotdotdot ... argument does not escape$" myprint1(nil, &j) // ERROR "dotdotdot ... argument does not escape$"
} }
func foo78(z int) *int { // ERROR "moved to heap: z$" func foo78(z int) *int { // ERROR "moved to heap: z$"
...@@ -739,11 +739,11 @@ func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param: p to resul ...@@ -739,11 +739,11 @@ func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param: p to resul
func noop(x, y *int) {} // ERROR "noop x does not escape$" "noop y does not escape$" func noop(x, y *int) {} // ERROR "noop x does not escape$" "noop y does not escape$"
func foo82() { func foo82() {
var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$" var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$"
go noop(tee(&z)) go noop(tee(&z))
go noop(&x, &y) go noop(&x, &y)
for { for {
var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$" var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$"
defer noop(tee(&u)) defer noop(tee(&u))
defer noop(&v, &w) defer noop(&v, &w)
} }
...@@ -916,22 +916,22 @@ func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$" ...@@ -916,22 +916,22 @@ func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
func foo116(b bool) *int { func foo116(b bool) *int {
if b { if b {
x := 1 // ERROR "moved to heap: x$" x := 1 // ERROR "moved to heap: x$"
return &x return &x
} else { } else {
y := 1 // ERROR "moved to heap: y$" y := 1 // ERROR "moved to heap: y$"
return &y return &y
} }
return nil return nil
} }
func foo117(unknown func(interface{})) { // ERROR "foo117 unknown does not escape$" func foo117(unknown func(interface{})) { // ERROR "foo117 unknown does not escape$"
x := 1 // ERROR "moved to heap: x$" x := 1 // ERROR "moved to heap: x$"
unknown(&x) // ERROR "&x escapes to heap$" unknown(&x)
} }
func foo118(unknown func(*int)) { // ERROR "foo118 unknown does not escape$" func foo118(unknown func(*int)) { // ERROR "foo118 unknown does not escape$"
x := 1 // ERROR "moved to heap: x$" x := 1 // ERROR "moved to heap: x$"
unknown(&x) unknown(&x)
} }
...@@ -1185,7 +1185,7 @@ L1: ...@@ -1185,7 +1185,7 @@ L1:
func foo124(x **int) { // ERROR "foo124 x does not escape$" func foo124(x **int) { // ERROR "foo124 x does not escape$"
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
func() { // ERROR "foo124 func literal does not escape$" func() { // ERROR "foo124 func literal does not escape$"
*x = p *x = p
}() }()
} }
...@@ -1193,7 +1193,7 @@ func foo124(x **int) { // ERROR "foo124 x does not escape$" ...@@ -1193,7 +1193,7 @@ func foo124(x **int) { // ERROR "foo124 x does not escape$"
func foo125(ch chan *int) { // ERROR "foo125 ch does not escape$" func foo125(ch chan *int) { // ERROR "foo125 ch does not escape$"
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
func() { // ERROR "foo125 func literal does not escape$" func() { // ERROR "foo125 func literal does not escape$"
ch <- p ch <- p
}() }()
} }
...@@ -1229,7 +1229,7 @@ func foo128() { ...@@ -1229,7 +1229,7 @@ func foo128() {
func foo129() { func foo129() {
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
func() { // ERROR "foo129 func literal does not escape$" func() { // ERROR "foo129 func literal does not escape$"
q := p q := p
func() { // ERROR "foo129.func1 func literal does not escape$" func() { // ERROR "foo129.func1 func literal does not escape$"
r := q r := q
...@@ -1281,7 +1281,7 @@ func foo134() { ...@@ -1281,7 +1281,7 @@ func foo134() {
} }
func foo135() { func foo135() {
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
go func() { // ERROR "func literal escapes to heap$" go func() { // ERROR "func literal escapes to heap$"
q := p q := p
...@@ -1293,7 +1293,7 @@ func foo135() { ...@@ -1293,7 +1293,7 @@ func foo135() {
} }
func foo136() { func foo136() {
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
go func() { // ERROR "func literal escapes to heap$" go func() { // ERROR "func literal escapes to heap$"
q := p q := p
...@@ -1307,7 +1307,7 @@ func foo136() { ...@@ -1307,7 +1307,7 @@ func foo136() {
func foo137() { func foo137() {
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
func() { // ERROR "foo137 func literal does not escape$" func() { // ERROR "foo137 func literal does not escape$"
q := p q := p
go func() { // ERROR "func literal escapes to heap$" go func() { // ERROR "func literal escapes to heap$"
r := q r := q
...@@ -1320,7 +1320,7 @@ func foo138() *byte { ...@@ -1320,7 +1320,7 @@ func foo138() *byte {
type T struct { type T struct {
x [1]byte x [1]byte
} }
t := new(T) // ERROR "new\(T\) escapes to heap$" t := new(T) // ERROR "new\(T\) escapes to heap$"
return &t.x[0] return &t.x[0]
} }
...@@ -1330,7 +1330,7 @@ func foo139() *byte { ...@@ -1330,7 +1330,7 @@ func foo139() *byte {
y byte y byte
} }
} }
t := new(T) // ERROR "new\(T\) escapes to heap$" t := new(T) // ERROR "new\(T\) escapes to heap$"
return &t.x.y return &t.x.y
} }
...@@ -1498,7 +1498,7 @@ func bar151() { ...@@ -1498,7 +1498,7 @@ func bar151() {
} }
func bar151b() { func bar151b() {
var a [10]int // ERROR "moved to heap: a$" var a [10]int // ERROR "moved to heap: a$"
b := a[:] b := a[:]
foo151(&b[4:8][0]) foo151(&b[4:8][0])
} }
...@@ -1510,7 +1510,7 @@ func bar151c() { ...@@ -1510,7 +1510,7 @@ func bar151c() {
} }
func bar151d() { func bar151d() {
var a [10]int // ERROR "moved to heap: a$" var a [10]int // ERROR "moved to heap: a$"
b := a[:] b := a[:]
foo151(&b[4:8:8][0]) foo151(&b[4:8:8][0])
} }
...@@ -1534,7 +1534,7 @@ func NewV(u U) *V { // ERROR "leaking param: u$" ...@@ -1534,7 +1534,7 @@ func NewV(u U) *V { // ERROR "leaking param: u$"
} }
func foo152() { func foo152() {
a := "a" // ERROR "moved to heap: a$" a := "a" // ERROR "moved to heap: a$"
u := U{&a} u := U{&a}
v := NewV(u) v := NewV(u)
println(v) println(v)
...@@ -1558,7 +1558,7 @@ func f() (x int, y *int) { // ERROR "moved to heap: x$" ...@@ -1558,7 +1558,7 @@ func f() (x int, y *int) { // ERROR "moved to heap: x$"
} }
func g() (x interface{}) { // ERROR "moved to heap: x$" func g() (x interface{}) { // ERROR "moved to heap: x$"
x = &x // ERROR "&x escapes to heap$" x = &x
return return
} }
...@@ -1579,14 +1579,14 @@ func ptrlitNoEscape2() { ...@@ -1579,14 +1579,14 @@ func ptrlitNoEscape2() {
// Literal does not escape, but element does. // Literal does not escape, but element does.
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x := &Lit{&i} // ERROR "ptrlitNoEscape2 &Lit literal does not escape$" x := &Lit{&i} // ERROR "ptrlitNoEscape2 &Lit literal does not escape$"
sink = *x // ERROR "\*x escapes to heap$" sink = *x
} }
func ptrlitEscape() { func ptrlitEscape() {
// Both literal and element escape. // Both literal and element escape.
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x := &Lit{&i} // ERROR "&Lit literal escapes to heap$" x := &Lit{&i} // ERROR "&Lit literal escapes to heap$"
sink = x // ERROR "x escapes to heap$" sink = x
} }
// self-assignments // self-assignments
...@@ -1624,7 +1624,7 @@ func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$" ...@@ -1624,7 +1624,7 @@ func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
func (b *Buffer) bat() { // ERROR "leaking param content: b$" func (b *Buffer) bat() { // ERROR "leaking param content: b$"
o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$" o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
o.buf1 = b.buf1[1:2] o.buf1 = b.buf1[1:2]
sink = o // ERROR "o escapes to heap$" sink = o
} }
func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$" func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
...@@ -1642,7 +1642,7 @@ type StructWithString struct { ...@@ -1642,7 +1642,7 @@ type StructWithString struct {
// to just x, and thus &i looks escaping. // to just x, and thus &i looks escaping.
func fieldFlowTracking() { func fieldFlowTracking() {
var x StructWithString var x StructWithString
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x.p = &i x.p = &i
sink = x.s // ERROR "x.s escapes to heap$" sink = x.s // ERROR "x.s escapes to heap$"
} }
...@@ -1666,7 +1666,7 @@ func slicebytetostring2() { ...@@ -1666,7 +1666,7 @@ func slicebytetostring2() {
b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$" b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$"
s := string(b) // ERROR "string\(b\) escapes to heap$" s := string(b) // ERROR "string\(b\) escapes to heap$"
s1 := s[0:1] // ERROR "moved to heap: s1$" s1 := s[0:1] // ERROR "moved to heap: s1$"
sink = &s1 // ERROR "&s1 escapes to heap$" sink = &s1
} }
func slicebytetostring3() { func slicebytetostring3() {
...@@ -1724,7 +1724,7 @@ func intstring2() { ...@@ -1724,7 +1724,7 @@ func intstring2() {
// string escapes to heap // string escapes to heap
x := '0' x := '0'
s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$" s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
sink = &s // ERROR "&s escapes to heap$" sink = &s
} }
func stringtoslicebyte0() { func stringtoslicebyte0() {
...@@ -1789,7 +1789,7 @@ func makemap1() map[int]int { ...@@ -1789,7 +1789,7 @@ func makemap1() map[int]int {
func makemap2() { func makemap2() {
m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$" m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
sink = m // ERROR "m escapes to heap$" sink = m
} }
func nonescapingEface(m map[interface{}]bool) bool { // ERROR "nonescapingEface m does not escape$" func nonescapingEface(m map[interface{}]bool) bool { // ERROR "nonescapingEface m does not escape$"
......
...@@ -146,13 +146,13 @@ func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$ ...@@ -146,13 +146,13 @@ func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$
} }
func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$" func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$"
v := 0 // ERROR "moved to heap: v$" v := 0 // ERROR "moved to heap: v$"
b.ii = &v b.ii = &v
return b.ii return b.ii
} }
func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$" func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$"
v := 0 // ERROR "moved to heap: v$" v := 0 // ERROR "moved to heap: v$"
b.ii = &v b.ii = &v
return b.ii return b.ii
} }
...@@ -465,12 +465,12 @@ func (MV) M() {} ...@@ -465,12 +465,12 @@ func (MV) M() {}
func foo65() { func foo65() {
var mv MV var mv MV
foo63(&mv) // ERROR "foo65 &mv does not escape$" foo63(&mv)
} }
func foo66() { func foo66() {
var mv MV // ERROR "moved to heap: mv$" var mv MV // ERROR "moved to heap: mv$"
foo64(&mv) // ERROR "&mv escapes to heap$" foo64(&mv)
} }
func foo67() { func foo67() {
...@@ -489,7 +489,7 @@ func foo69(m M) { // ERROR "leaking param: m$" ...@@ -489,7 +489,7 @@ func foo69(m M) { // ERROR "leaking param: m$"
} }
func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$" func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
m = mv1 // ERROR "mv1 escapes to heap$" m = mv1
foo64(m) foo64(m)
} }
...@@ -522,7 +522,7 @@ func foo72a() { ...@@ -522,7 +522,7 @@ func foo72a() {
var y [10]*int var y [10]*int
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
// escapes its scope // escapes its scope
x := i // ERROR "moved to heap: x$" x := i // ERROR "moved to heap: x$"
y[i] = &x y[i] = &x
} }
return return
...@@ -531,7 +531,7 @@ func foo72a() { ...@@ -531,7 +531,7 @@ func foo72a() {
func foo72b() [10]*int { func foo72b() [10]*int {
var y [10]*int var y [10]*int
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
x := i // ERROR "moved to heap: x$" x := i // ERROR "moved to heap: x$"
y[i] = &x y[i] = &x
} }
return y return y
...@@ -637,15 +637,15 @@ func foo75aesc(z *int) { // ERROR "foo75aesc z does not escape$" ...@@ -637,15 +637,15 @@ func foo75aesc(z *int) { // ERROR "foo75aesc z does not escape$"
} }
func foo75aesc1(z *int) { // ERROR "foo75aesc1 z does not escape$" 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$" sink = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
} }
func foo76(z *int) { // ERROR "z does not escape" func foo76(z *int) { // ERROR "z does not escape"
myprint(nil, z) // ERROR "foo76 ... argument does not escape$" "z does not escape" myprint(nil, z) // ERROR "foo76 ... argument does not escape$"
} }
func foo76a(z *int) { // ERROR "z does not escape" func foo76a(z *int) { // ERROR "z does not escape"
myprint1(nil, z) // ERROR "foo76a ... argument does not escape$" "z does not escape" myprint1(nil, z) // ERROR "foo76a ... argument does not escape$"
} }
func foo76b() { func foo76b() {
...@@ -691,15 +691,15 @@ func foo77b(z []interface{}) { // ERROR "leaking param: z$" ...@@ -691,15 +691,15 @@ func foo77b(z []interface{}) { // ERROR "leaking param: z$"
} }
func foo77c(z []interface{}) { // ERROR "leaking param: z$" func foo77c(z []interface{}) { // ERROR "leaking param: z$"
sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z...\) escapes to heap$" sink = myprint1(nil, z...)
} }
func dotdotdot() { func dotdotdot() {
i := 0 i := 0
myprint(nil, &i) // ERROR "&i does not escape" "dotdotdot ... argument does not escape$" myprint(nil, &i) // ERROR "dotdotdot ... argument does not escape$"
j := 0 j := 0
myprint1(nil, &j) // ERROR "&j does not escape" "dotdotdot ... argument does not escape$" myprint1(nil, &j) // ERROR "dotdotdot ... argument does not escape$"
} }
func foo78(z int) *int { // ERROR "moved to heap: z$" func foo78(z int) *int { // ERROR "moved to heap: z$"
...@@ -739,11 +739,11 @@ func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param: p to resul ...@@ -739,11 +739,11 @@ func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param: p to resul
func noop(x, y *int) {} // ERROR "noop x does not escape$" "noop y does not escape$" func noop(x, y *int) {} // ERROR "noop x does not escape$" "noop y does not escape$"
func foo82() { func foo82() {
var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$" var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$"
go noop(tee(&z)) go noop(tee(&z))
go noop(&x, &y) go noop(&x, &y)
for { for {
var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$" var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$"
defer noop(tee(&u)) defer noop(tee(&u))
defer noop(&v, &w) defer noop(&v, &w)
} }
...@@ -916,22 +916,22 @@ func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$" ...@@ -916,22 +916,22 @@ func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
func foo116(b bool) *int { func foo116(b bool) *int {
if b { if b {
x := 1 // ERROR "moved to heap: x$" x := 1 // ERROR "moved to heap: x$"
return &x return &x
} else { } else {
y := 1 // ERROR "moved to heap: y$" y := 1 // ERROR "moved to heap: y$"
return &y return &y
} }
return nil return nil
} }
func foo117(unknown func(interface{})) { // ERROR "foo117 unknown does not escape$" func foo117(unknown func(interface{})) { // ERROR "foo117 unknown does not escape$"
x := 1 // ERROR "moved to heap: x$" x := 1 // ERROR "moved to heap: x$"
unknown(&x) // ERROR "&x escapes to heap$" unknown(&x)
} }
func foo118(unknown func(*int)) { // ERROR "foo118 unknown does not escape$" func foo118(unknown func(*int)) { // ERROR "foo118 unknown does not escape$"
x := 1 // ERROR "moved to heap: x$" x := 1 // ERROR "moved to heap: x$"
unknown(&x) unknown(&x)
} }
...@@ -1185,7 +1185,7 @@ L1: ...@@ -1185,7 +1185,7 @@ L1:
func foo124(x **int) { // ERROR "foo124 x does not escape$" func foo124(x **int) { // ERROR "foo124 x does not escape$"
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
func() { // ERROR "foo124 func literal does not escape$" func() { // ERROR "foo124 func literal does not escape$"
*x = p *x = p
}() }()
} }
...@@ -1193,7 +1193,7 @@ func foo124(x **int) { // ERROR "foo124 x does not escape$" ...@@ -1193,7 +1193,7 @@ func foo124(x **int) { // ERROR "foo124 x does not escape$"
func foo125(ch chan *int) { // ERROR "foo125 ch does not escape$" func foo125(ch chan *int) { // ERROR "foo125 ch does not escape$"
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
func() { // ERROR "foo125 func literal does not escape$" func() { // ERROR "foo125 func literal does not escape$"
ch <- p ch <- p
}() }()
} }
...@@ -1229,7 +1229,7 @@ func foo128() { ...@@ -1229,7 +1229,7 @@ func foo128() {
func foo129() { func foo129() {
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
func() { // ERROR "foo129 func literal does not escape$" func() { // ERROR "foo129 func literal does not escape$"
q := p q := p
func() { // ERROR "foo129.func1 func literal does not escape$" func() { // ERROR "foo129.func1 func literal does not escape$"
r := q r := q
...@@ -1281,7 +1281,7 @@ func foo134() { ...@@ -1281,7 +1281,7 @@ func foo134() {
} }
func foo135() { func foo135() {
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
go func() { // ERROR "func literal escapes to heap$" go func() { // ERROR "func literal escapes to heap$"
q := p q := p
...@@ -1293,7 +1293,7 @@ func foo135() { ...@@ -1293,7 +1293,7 @@ func foo135() {
} }
func foo136() { func foo136() {
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
go func() { // ERROR "func literal escapes to heap$" go func() { // ERROR "func literal escapes to heap$"
q := p q := p
...@@ -1307,7 +1307,7 @@ func foo136() { ...@@ -1307,7 +1307,7 @@ func foo136() {
func foo137() { func foo137() {
var i int // ERROR "moved to heap: i$" var i int // ERROR "moved to heap: i$"
p := &i p := &i
func() { // ERROR "foo137 func literal does not escape$" func() { // ERROR "foo137 func literal does not escape$"
q := p q := p
go func() { // ERROR "func literal escapes to heap$" go func() { // ERROR "func literal escapes to heap$"
r := q r := q
...@@ -1320,7 +1320,7 @@ func foo138() *byte { ...@@ -1320,7 +1320,7 @@ func foo138() *byte {
type T struct { type T struct {
x [1]byte x [1]byte
} }
t := new(T) // ERROR "new\(T\) escapes to heap$" t := new(T) // ERROR "new\(T\) escapes to heap$"
return &t.x[0] return &t.x[0]
} }
...@@ -1330,7 +1330,7 @@ func foo139() *byte { ...@@ -1330,7 +1330,7 @@ func foo139() *byte {
y byte y byte
} }
} }
t := new(T) // ERROR "new\(T\) escapes to heap$" t := new(T) // ERROR "new\(T\) escapes to heap$"
return &t.x.y return &t.x.y
} }
...@@ -1498,7 +1498,7 @@ func bar151() { ...@@ -1498,7 +1498,7 @@ func bar151() {
} }
func bar151b() { func bar151b() {
var a [10]int // ERROR "moved to heap: a$" var a [10]int // ERROR "moved to heap: a$"
b := a[:] b := a[:]
foo151(&b[4:8][0]) foo151(&b[4:8][0])
} }
...@@ -1510,7 +1510,7 @@ func bar151c() { ...@@ -1510,7 +1510,7 @@ func bar151c() {
} }
func bar151d() { func bar151d() {
var a [10]int // ERROR "moved to heap: a$" var a [10]int // ERROR "moved to heap: a$"
b := a[:] b := a[:]
foo151(&b[4:8:8][0]) foo151(&b[4:8:8][0])
} }
...@@ -1534,7 +1534,7 @@ func NewV(u U) *V { // ERROR "leaking param: u$" ...@@ -1534,7 +1534,7 @@ func NewV(u U) *V { // ERROR "leaking param: u$"
} }
func foo152() { func foo152() {
a := "a" // ERROR "moved to heap: a$" a := "a" // ERROR "moved to heap: a$"
u := U{&a} u := U{&a}
v := NewV(u) v := NewV(u)
println(v) println(v)
...@@ -1558,7 +1558,7 @@ func f() (x int, y *int) { // ERROR "moved to heap: x$" ...@@ -1558,7 +1558,7 @@ func f() (x int, y *int) { // ERROR "moved to heap: x$"
} }
func g() (x interface{}) { // ERROR "moved to heap: x$" func g() (x interface{}) { // ERROR "moved to heap: x$"
x = &x // ERROR "&x escapes to heap$" x = &x
return return
} }
...@@ -1579,14 +1579,14 @@ func ptrlitNoEscape2() { ...@@ -1579,14 +1579,14 @@ func ptrlitNoEscape2() {
// Literal does not escape, but element does. // Literal does not escape, but element does.
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x := &Lit{&i} // ERROR "ptrlitNoEscape2 &Lit literal does not escape$" x := &Lit{&i} // ERROR "ptrlitNoEscape2 &Lit literal does not escape$"
sink = *x // ERROR "\*x escapes to heap$" sink = *x
} }
func ptrlitEscape() { func ptrlitEscape() {
// Both literal and element escape. // Both literal and element escape.
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x := &Lit{&i} // ERROR "&Lit literal escapes to heap$" x := &Lit{&i} // ERROR "&Lit literal escapes to heap$"
sink = x // ERROR "x escapes to heap$" sink = x
} }
// self-assignments // self-assignments
...@@ -1624,7 +1624,7 @@ func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$" ...@@ -1624,7 +1624,7 @@ func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
func (b *Buffer) bat() { // ERROR "leaking param content: b$" func (b *Buffer) bat() { // ERROR "leaking param content: b$"
o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$" o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
o.buf1 = b.buf1[1:2] o.buf1 = b.buf1[1:2]
sink = o // ERROR "o escapes to heap$" sink = o
} }
func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$" func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
...@@ -1642,7 +1642,7 @@ type StructWithString struct { ...@@ -1642,7 +1642,7 @@ type StructWithString struct {
// to just x, and thus &i looks escaping. // to just x, and thus &i looks escaping.
func fieldFlowTracking() { func fieldFlowTracking() {
var x StructWithString var x StructWithString
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x.p = &i x.p = &i
sink = x.s // ERROR "x.s escapes to heap$" sink = x.s // ERROR "x.s escapes to heap$"
} }
...@@ -1666,7 +1666,7 @@ func slicebytetostring2() { ...@@ -1666,7 +1666,7 @@ func slicebytetostring2() {
b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$" b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$"
s := string(b) // ERROR "string\(b\) escapes to heap$" s := string(b) // ERROR "string\(b\) escapes to heap$"
s1 := s[0:1] // ERROR "moved to heap: s1$" s1 := s[0:1] // ERROR "moved to heap: s1$"
sink = &s1 // ERROR "&s1 escapes to heap$" sink = &s1
} }
func slicebytetostring3() { func slicebytetostring3() {
...@@ -1724,7 +1724,7 @@ func intstring2() { ...@@ -1724,7 +1724,7 @@ func intstring2() {
// string escapes to heap // string escapes to heap
x := '0' x := '0'
s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$" s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
sink = &s // ERROR "&s escapes to heap$" sink = &s
} }
func stringtoslicebyte0() { func stringtoslicebyte0() {
...@@ -1789,7 +1789,7 @@ func makemap1() map[int]int { ...@@ -1789,7 +1789,7 @@ func makemap1() map[int]int {
func makemap2() { func makemap2() {
m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$" m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
sink = m // ERROR "m escapes to heap$" sink = m
} }
func nonescapingEface(m map[interface{}]bool) bool { // ERROR "nonescapingEface m does not escape$" func nonescapingEface(m map[interface{}]bool) bool { // ERROR "nonescapingEface m does not escape$"
......
...@@ -139,7 +139,7 @@ func f8(p *T1) (k T2) { // ERROR "leaking param: p$" ...@@ -139,7 +139,7 @@ func f8(p *T1) (k T2) { // ERROR "leaking param: p$"
} }
// should make p leak always // should make p leak always
global = p // ERROR "p escapes to heap" global = p
return T2{p} return T2{p}
} }
...@@ -164,7 +164,7 @@ func f13() { ...@@ -164,7 +164,7 @@ func f13() {
var x *int var x *int
f11(&x) f11(&x)
f12(&x) f12(&x)
runtime.KeepAlive(&x) // ERROR "&x does not escape" runtime.KeepAlive(&x)
} }
// Test for issue 24305 (passing to unnamed receivers does not escape). // Test for issue 24305 (passing to unnamed receivers does not escape).
......
...@@ -38,7 +38,7 @@ func ClosureCallArgs2() { ...@@ -38,7 +38,7 @@ func ClosureCallArgs2() {
func ClosureCallArgs3() { func ClosureCallArgs3() {
x := 0 // ERROR "moved to heap: x" x := 0 // ERROR "moved to heap: x"
func(p *int) { // ERROR "leaking param: p" "func literal does not escape" func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
sink = p // ERROR "p escapes to heap" sink = p
}(&x) }(&x)
} }
...@@ -53,7 +53,7 @@ func ClosureCallArgs5() { ...@@ -53,7 +53,7 @@ func ClosureCallArgs5() {
x := 0 // ERROR "moved to heap: x" x := 0 // ERROR "moved to heap: x"
// TODO(mdempsky): We get "leaking param: p" here because the new escape analysis pass // TODO(mdempsky): We get "leaking param: p" here because the new escape analysis pass
// can tell that p flows directly to sink, but it's a little weird. Re-evaluate. // can tell that p flows directly to sink, but it's a little weird. Re-evaluate.
sink = func(p *int) *int { // ERROR "leaking param: p" "func literal does not escape" "\(func literal\)\(&x\) escapes to heap" sink = func(p *int) *int { // ERROR "leaking param: p" "func literal does not escape"
return p return p
}(&x) }(&x)
} }
...@@ -61,7 +61,7 @@ func ClosureCallArgs5() { ...@@ -61,7 +61,7 @@ func ClosureCallArgs5() {
func ClosureCallArgs6() { func ClosureCallArgs6() {
x := 0 // ERROR "moved to heap: x" x := 0 // ERROR "moved to heap: x"
func(p *int) { // ERROR "moved to heap: p" "func literal does not escape" func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
sink = &p // ERROR "&p escapes to heap" sink = &p
}(&x) }(&x)
} }
...@@ -105,7 +105,7 @@ func ClosureCallArgs10() { ...@@ -105,7 +105,7 @@ func ClosureCallArgs10() {
func ClosureCallArgs11() { func ClosureCallArgs11() {
x := 0 // ERROR "moved to heap: x" x := 0 // ERROR "moved to heap: x"
defer func(p *int) { // ERROR "leaking param: p" "func literal does not escape" defer func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
sink = p // ERROR "p escapes to heap" sink = p
}(&x) }(&x)
} }
...@@ -119,7 +119,7 @@ func ClosureCallArgs12() { ...@@ -119,7 +119,7 @@ func ClosureCallArgs12() {
func ClosureCallArgs13() { func ClosureCallArgs13() {
x := 0 // ERROR "moved to heap: x" x := 0 // ERROR "moved to heap: x"
defer func(p *int) { // ERROR "moved to heap: p" "func literal does not escape" defer func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
sink = &p // ERROR "&p escapes to heap" sink = &p
}(&x) }(&x)
} }
...@@ -134,7 +134,7 @@ func ClosureCallArgs14() { ...@@ -134,7 +134,7 @@ func ClosureCallArgs14() {
func ClosureCallArgs15() { func ClosureCallArgs15() {
x := 0 // ERROR "moved to heap: x" x := 0 // ERROR "moved to heap: x"
p := &x p := &x
sink = func(p **int) *int { // ERROR "leaking param content: p" "func literal does not escape" "\(func literal\)\(&p\) escapes to heap" sink = func(p **int) *int { // ERROR "leaking param content: p" "func literal does not escape"
return *p return *p
}(&p) }(&p)
} }
......
...@@ -24,7 +24,7 @@ func field0() { ...@@ -24,7 +24,7 @@ func field0() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
var x X var x X
x.p1 = &i x.p1 = &i
sink = x.p1 // ERROR "x\.p1 escapes to heap" sink = x.p1
} }
func field1() { func field1() {
...@@ -32,14 +32,14 @@ func field1() { ...@@ -32,14 +32,14 @@ func field1() {
var x X var x X
// BAD: &i should not escape // BAD: &i should not escape
x.p1 = &i x.p1 = &i
sink = x.p2 // ERROR "x\.p2 escapes to heap" sink = x.p2
} }
func field3() { func field3() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
var x X var x X
x.p1 = &i x.p1 = &i
sink = x // ERROR "x escapes to heap" sink = x // ERROR "x escapes to heap"
} }
func field4() { func field4() {
...@@ -55,12 +55,12 @@ func field5() { ...@@ -55,12 +55,12 @@ func field5() {
var x X var x X
// BAD: &i should not escape here // BAD: &i should not escape here
x.a[0] = &i x.a[0] = &i
sink = x.a[1] // ERROR "x\.a\[1\] escapes to heap" sink = x.a[1]
} }
// BAD: we are not leaking param x, only x.p2 // BAD: we are not leaking param x, only x.p2
func field6(x *X) { // ERROR "leaking param content: x$" func field6(x *X) { // ERROR "leaking param content: x$"
sink = x.p2 // ERROR "x\.p2 escapes to heap" sink = x.p2
} }
func field6a() { func field6a() {
...@@ -88,7 +88,7 @@ func field8() { ...@@ -88,7 +88,7 @@ func field8() {
x := y.x x := y.x
var y1 Y var y1 Y
y1.x = x y1.x = x
sink = y1.x.p1 // ERROR "y1\.x\.p1 escapes to heap" sink = y1.x.p1
} }
func field9() { func field9() {
...@@ -109,39 +109,39 @@ func field10() { ...@@ -109,39 +109,39 @@ func field10() {
x := y.x x := y.x
var y1 Y var y1 Y
y1.x = x y1.x = x
sink = y1.x.p2 // ERROR "y1\.x\.p2 escapes to heap" sink = y1.x.p2
} }
func field11() { func field11() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x := X{p1: &i} x := X{p1: &i}
sink = x.p1 // ERROR "x\.p1 escapes to heap" sink = x.p1
} }
func field12() { func field12() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
// BAD: &i should not escape // BAD: &i should not escape
x := X{p1: &i} x := X{p1: &i}
sink = x.p2 // ERROR "x\.p2 escapes to heap" sink = x.p2
} }
func field13() { func field13() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x := &X{p1: &i} // ERROR "field13 &X literal does not escape$" x := &X{p1: &i} // ERROR "field13 &X literal does not escape$"
sink = x.p1 // ERROR "x\.p1 escapes to heap" sink = x.p1
} }
func field14() { func field14() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
// BAD: &i should not escape // BAD: &i should not escape
x := &X{p1: &i} // ERROR "field14 &X literal does not escape$" x := &X{p1: &i} // ERROR "field14 &X literal does not escape$"
sink = x.p2 // ERROR "x\.p2 escapes to heap" sink = x.p2
} }
func field15() { func field15() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
x := &X{p1: &i} // ERROR "&X literal escapes to heap$" x := &X{p1: &i} // ERROR "&X literal escapes to heap$"
sink = x // ERROR "x escapes to heap" sink = x
} }
func field16() { func field16() {
...@@ -151,7 +151,7 @@ func field16() { ...@@ -151,7 +151,7 @@ func field16() {
x.p1 = &i x.p1 = &i
var iface interface{} = x // ERROR "field16 x does not escape" var iface interface{} = x // ERROR "field16 x does not escape"
x1 := iface.(X) x1 := iface.(X)
sink = x1.p2 // ERROR "x1\.p2 escapes to heap" sink = x1.p2
} }
func field17() { func field17() {
...@@ -160,7 +160,7 @@ func field17() { ...@@ -160,7 +160,7 @@ func field17() {
x.p1 = &i x.p1 = &i
var iface interface{} = x // ERROR "field17 x does not escape" var iface interface{} = x // ERROR "field17 x does not escape"
x1 := iface.(X) x1 := iface.(X)
sink = x1.p1 // ERROR "x1\.p1 escapes to heap" sink = x1.p1
} }
func field18() { func field18() {
......
...@@ -15,7 +15,7 @@ type M interface { ...@@ -15,7 +15,7 @@ type M interface {
} }
func mescapes(m M) { // ERROR "leaking param: m" func mescapes(m M) { // ERROR "leaking param: m"
sink = m // ERROR "m escapes to heap" sink = m
} }
func mdoesnotescape(m M) { // ERROR "m does not escape" func mdoesnotescape(m M) { // ERROR "m does not escape"
...@@ -33,19 +33,19 @@ func efaceEscape0() { ...@@ -33,19 +33,19 @@ func efaceEscape0() {
{ {
i := 0 i := 0
v := M0{&i} v := M0{&i}
var x M = v // ERROR "v does not escape" var x M = v
_ = x _ = x
} }
{ {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := M0{&i} v := M0{&i}
var x M = v // ERROR "v escapes to heap" var x M = v
sink = x // ERROR "x escapes to heap" sink = x
} }
{ {
i := 0 i := 0
v := M0{&i} v := M0{&i}
var x M = v // ERROR "v does not escape" var x M = v
v1 := x.(M0) v1 := x.(M0)
_ = v1 _ = v1
} }
...@@ -53,27 +53,27 @@ func efaceEscape0() { ...@@ -53,27 +53,27 @@ func efaceEscape0() {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := M0{&i} v := M0{&i}
// BAD: v does not escape to heap here // BAD: v does not escape to heap here
var x M = v // ERROR "v escapes to heap" var x M = v
v1 := x.(M0) v1 := x.(M0)
sink = v1 // ERROR "v1 escapes to heap" sink = v1
} }
{ {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := M0{&i} v := M0{&i}
// BAD: v does not escape to heap here // BAD: v does not escape to heap here
var x M = v // ERROR "v escapes to heap" var x M = v
x.M() x.M()
} }
{ {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := M0{&i} v := M0{&i}
var x M = v // ERROR "v escapes to heap" var x M = v
mescapes(x) mescapes(x)
} }
{ {
i := 0 i := 0
v := M0{&i} v := M0{&i}
var x M = v // ERROR "v does not escape" var x M = v
mdoesnotescape(x) mdoesnotescape(x)
} }
} }
...@@ -98,7 +98,7 @@ func efaceEscape1() { ...@@ -98,7 +98,7 @@ func efaceEscape1() {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := M1{&i, 0} v := M1{&i, 0}
var x M = v // ERROR "v escapes to heap" var x M = v // ERROR "v escapes to heap"
sink = x // ERROR "x escapes to heap" sink = x
} }
{ {
i := 0 i := 0
...@@ -147,19 +147,19 @@ func efaceEscape2() { ...@@ -147,19 +147,19 @@ func efaceEscape2() {
{ {
i := 0 i := 0
v := &M2{&i} // ERROR "&M2 literal does not escape" v := &M2{&i} // ERROR "&M2 literal does not escape"
var x M = v // ERROR "v does not escape" var x M = v
_ = x _ = x
} }
{ {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal escapes to heap" v := &M2{&i} // ERROR "&M2 literal escapes to heap"
var x M = v // ERROR "v escapes to heap" var x M = v
sink = x // ERROR "x escapes to heap" sink = x
} }
{ {
i := 0 i := 0
v := &M2{&i} // ERROR "&M2 literal does not escape" v := &M2{&i} // ERROR "&M2 literal does not escape"
var x M = v // ERROR "v does not escape" var x M = v
v1 := x.(*M2) v1 := x.(*M2)
_ = v1 _ = v1
} }
...@@ -167,44 +167,44 @@ func efaceEscape2() { ...@@ -167,44 +167,44 @@ func efaceEscape2() {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal escapes to heap" v := &M2{&i} // ERROR "&M2 literal escapes to heap"
// BAD: v does not escape to heap here // BAD: v does not escape to heap here
var x M = v // ERROR "v escapes to heap" var x M = v
v1 := x.(*M2) v1 := x.(*M2)
sink = v1 // ERROR "v1 escapes to heap" sink = v1
} }
{ {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal does not escape" v := &M2{&i} // ERROR "&M2 literal does not escape"
// BAD: v does not escape to heap here // BAD: v does not escape to heap here
var x M = v // ERROR "v does not escape" var x M = v
v1 := x.(*M2) v1 := x.(*M2)
sink = *v1 // ERROR "v1 escapes to heap" sink = *v1
} }
{ {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal does not escape" v := &M2{&i} // ERROR "&M2 literal does not escape"
// BAD: v does not escape to heap here // BAD: v does not escape to heap here
var x M = v // ERROR "v does not escape" var x M = v
v1, ok := x.(*M2) v1, ok := x.(*M2)
sink = *v1 // ERROR "v1 escapes to heap" sink = *v1
_ = ok _ = ok
} }
{ {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal escapes to heap" v := &M2{&i} // ERROR "&M2 literal escapes to heap"
// BAD: v does not escape to heap here // BAD: v does not escape to heap here
var x M = v // ERROR "v escapes to heap" var x M = v
x.M() x.M()
} }
{ {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal escapes to heap" v := &M2{&i} // ERROR "&M2 literal escapes to heap"
var x M = v // ERROR "v escapes to heap" var x M = v
mescapes(x) mescapes(x)
} }
{ {
i := 0 i := 0
v := &M2{&i} // ERROR "&M2 literal does not escape" v := &M2{&i} // ERROR "&M2 literal does not escape"
var x M = v // ERROR "v does not escape" var x M = v
mdoesnotescape(x) mdoesnotescape(x)
} }
} }
...@@ -251,10 +251,10 @@ func dotTypeEscape2() { // #13805, #15796 ...@@ -251,10 +251,10 @@ func dotTypeEscape2() { // #13805, #15796
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
j := 0 // ERROR "moved to heap: j" j := 0 // ERROR "moved to heap: j"
var ok bool var ok bool
var x interface{} = &i // ERROR "&i escapes to heap" var x interface{} = &i
var y interface{} = &j // ERROR "&j escapes to heap" var y interface{} = &j
sink = x.(*int) // ERROR "x.\(\*int\) escapes to heap" sink = x.(*int)
sink, *(&ok) = y.(*int) sink, *(&ok) = y.(*int)
} }
} }
...@@ -54,7 +54,7 @@ func constptr1() { ...@@ -54,7 +54,7 @@ func constptr1() {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap" x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap"
x.p = &i x.p = &i
sink = x // ERROR "x escapes to heap" sink = x
} }
func constptr2() { func constptr2() {
...@@ -144,7 +144,7 @@ func foo2() { ...@@ -144,7 +144,7 @@ func foo2() {
f **int f **int
} }
x := new(int) // ERROR "moved to heap: x" "new\(int\) escapes to heap" x := new(int) // ERROR "moved to heap: x" "new\(int\) escapes to heap"
sink = &x // ERROR "&x escapes to heap" sink = &x
var z Z var z Z
z.f = &x z.f = &x
p := z.f p := z.f
......
...@@ -15,7 +15,7 @@ func level0() { ...@@ -15,7 +15,7 @@ func level0() {
p0 := &i // ERROR "moved to heap: p0" p0 := &i // ERROR "moved to heap: p0"
p1 := &p0 // ERROR "moved to heap: p1" p1 := &p0 // ERROR "moved to heap: p1"
p2 := &p1 // ERROR "moved to heap: p2" p2 := &p1 // ERROR "moved to heap: p2"
sink = &p2 // ERROR "&p2 escapes to heap" sink = &p2
} }
func level1() { func level1() {
...@@ -23,7 +23,7 @@ func level1() { ...@@ -23,7 +23,7 @@ func level1() {
p0 := &i // ERROR "moved to heap: p0" p0 := &i // ERROR "moved to heap: p0"
p1 := &p0 // ERROR "moved to heap: p1" p1 := &p0 // ERROR "moved to heap: p1"
p2 := &p1 p2 := &p1
sink = p2 // ERROR "p2 escapes to heap" sink = p2
} }
func level2() { func level2() {
...@@ -31,7 +31,7 @@ func level2() { ...@@ -31,7 +31,7 @@ func level2() {
p0 := &i // ERROR "moved to heap: p0" p0 := &i // ERROR "moved to heap: p0"
p1 := &p0 p1 := &p0
p2 := &p1 p2 := &p1
sink = *p2 // ERROR "\*p2 escapes to heap" sink = *p2
} }
func level3() { func level3() {
...@@ -39,7 +39,7 @@ func level3() { ...@@ -39,7 +39,7 @@ func level3() {
p0 := &i p0 := &i
p1 := &p0 p1 := &p0
p2 := &p1 p2 := &p1
sink = **p2 // ERROR "\* \(\*p2\) escapes to heap" sink = **p2
} }
func level4() { func level4() {
...@@ -47,7 +47,7 @@ func level4() { ...@@ -47,7 +47,7 @@ func level4() {
p0 := &i // ERROR "moved to heap: p0" p0 := &i // ERROR "moved to heap: p0"
p1 := &p0 p1 := &p0
p2 := p1 // ERROR "moved to heap: p2" p2 := p1 // ERROR "moved to heap: p2"
sink = &p2 // ERROR "&p2 escapes to heap" sink = &p2
} }
func level5() { func level5() {
...@@ -55,7 +55,7 @@ func level5() { ...@@ -55,7 +55,7 @@ func level5() {
p0 := &i // ERROR "moved to heap: p0" p0 := &i // ERROR "moved to heap: p0"
p1 := &p0 p1 := &p0
p2 := p1 p2 := p1
sink = p2 // ERROR "p2 escapes to heap" sink = p2
} }
func level6() { func level6() {
...@@ -63,7 +63,7 @@ func level6() { ...@@ -63,7 +63,7 @@ func level6() {
p0 := &i p0 := &i
p1 := &p0 p1 := &p0
p2 := p1 p2 := p1
sink = *p2 // ERROR "\*p2 escapes to heap" sink = *p2
} }
func level7() { func level7() {
...@@ -72,7 +72,7 @@ func level7() { ...@@ -72,7 +72,7 @@ func level7() {
p1 := &p0 p1 := &p0
// note *p1 == &i // note *p1 == &i
p2 := *p1 // ERROR "moved to heap: p2" p2 := *p1 // ERROR "moved to heap: p2"
sink = &p2 // ERROR "&p2 escapes to heap" sink = &p2
} }
func level8() { func level8() {
...@@ -80,7 +80,7 @@ func level8() { ...@@ -80,7 +80,7 @@ func level8() {
p0 := &i p0 := &i
p1 := &p0 p1 := &p0
p2 := *p1 p2 := *p1
sink = p2 // ERROR "p2 escapes to heap" sink = p2
} }
func level9() { func level9() {
...@@ -104,5 +104,5 @@ func level11() { ...@@ -104,5 +104,5 @@ func level11() {
p0 := &i p0 := &i
p1 := &p0 p1 := &p0
p2 := **p1 // ERROR "moved to heap: p2" p2 := **p1 // ERROR "moved to heap: p2"
sink = &p2 // ERROR "&p2 escapes to heap" sink = &p2
} }
...@@ -95,7 +95,7 @@ func map8() { ...@@ -95,7 +95,7 @@ func map8() {
i := 0 // ERROR "moved to heap: i" i := 0 // ERROR "moved to heap: i"
j := 0 // ERROR "moved to heap: j" j := 0 // ERROR "moved to heap: j"
m := map[*int]*int{&i: &j} // ERROR "literal escapes to heap" m := map[*int]*int{&i: &j} // ERROR "literal escapes to heap"
sink = m // ERROR "m escapes to heap" sink = m
} }
func map9() *int { func map9() *int {
......
...@@ -27,7 +27,7 @@ func caller0a() { ...@@ -27,7 +27,7 @@ func caller0a() {
func caller0b() { func caller0b() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
sink = param0(&i) // ERROR "param0\(&i\) escapes to heap" sink = param0(&i)
} }
// in, in -> out, out // in, in -> out, out
...@@ -57,7 +57,7 @@ func caller2b() { ...@@ -57,7 +57,7 @@ func caller2b() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
var p *int var p *int
param2(&i, &p) param2(&i, &p)
sink = p // ERROR "p escapes to heap$" sink = p
} }
func paramArraySelfAssign(p *PairOfPairs) { // ERROR "p does not escape" func paramArraySelfAssign(p *PairOfPairs) { // ERROR "p does not escape"
...@@ -88,27 +88,27 @@ func leakParam(x interface{}) { // ERROR "leaking param: x" ...@@ -88,27 +88,27 @@ func leakParam(x interface{}) { // ERROR "leaking param: x"
func sinkAfterSelfAssignment1(box *BoxedPair) { // ERROR "leaking param content: box" func sinkAfterSelfAssignment1(box *BoxedPair) { // ERROR "leaking param content: box"
box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2" box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
sink = box.pair.p2 // ERROR "box.pair.p2 escapes to heap" sink = box.pair.p2
} }
func sinkAfterSelfAssignment2(box *BoxedPair) { // ERROR "leaking param content: box" func sinkAfterSelfAssignment2(box *BoxedPair) { // ERROR "leaking param content: box"
box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2" box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
sink = box.pair // ERROR "box.pair escapes to heap" sink = box.pair
} }
func sinkAfterSelfAssignment3(box *BoxedPair) { // ERROR "leaking param content: box" func sinkAfterSelfAssignment3(box *BoxedPair) { // ERROR "leaking param content: box"
box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2" box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
leakParam(box.pair.p2) // ERROR "box.pair.p2 escapes to heap" leakParam(box.pair.p2)
} }
func sinkAfterSelfAssignment4(box *BoxedPair) { // ERROR "leaking param content: box" func sinkAfterSelfAssignment4(box *BoxedPair) { // ERROR "leaking param content: box"
box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2" box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
leakParam(box.pair) // ERROR "box.pair escapes to heap" leakParam(box.pair)
} }
func selfAssignmentAndUnrelated(box1, box2 *BoxedPair) { // ERROR "leaking param content: box2" "box1 does not escape" func selfAssignmentAndUnrelated(box1, box2 *BoxedPair) { // ERROR "leaking param content: box2" "box1 does not escape"
box1.pair.p1 = box1.pair.p2 // ERROR "ignoring self-assignment in box1.pair.p1 = box1.pair.p2" box1.pair.p1 = box1.pair.p2 // ERROR "ignoring self-assignment in box1.pair.p1 = box1.pair.p2"
leakParam(box2.pair.p2) // ERROR "box2.pair.p2 escapes to heap" leakParam(box2.pair.p2)
} }
func notSelfAssignment1(box1, box2 *BoxedPair) { // ERROR "leaking param content: box2" "box1 does not escape" func notSelfAssignment1(box1, box2 *BoxedPair) { // ERROR "leaking param content: box2" "box1 does not escape"
...@@ -178,7 +178,7 @@ func caller4b() { ...@@ -178,7 +178,7 @@ func caller4b() {
// in -> heap // in -> heap
func param5(i *int) { // ERROR "leaking param: i$" func param5(i *int) { // ERROR "leaking param: i$"
sink = i // ERROR "i escapes to heap$" sink = i
} }
func caller5() { func caller5() {
...@@ -188,7 +188,7 @@ func caller5() { ...@@ -188,7 +188,7 @@ func caller5() {
// *in -> heap // *in -> heap
func param6(i ***int) { // ERROR "leaking param content: i$" func param6(i ***int) { // ERROR "leaking param content: i$"
sink = *i // ERROR "\*i escapes to heap$" sink = *i
} }
func caller6a() { func caller6a() {
...@@ -200,7 +200,7 @@ func caller6a() { ...@@ -200,7 +200,7 @@ func caller6a() {
// **in -> heap // **in -> heap
func param7(i ***int) { // ERROR "leaking param content: i$" func param7(i ***int) { // ERROR "leaking param content: i$"
sink = **i // ERROR "\* \(\*i\) escapes to heap" sink = **i
} }
func caller7() { func caller7() {
...@@ -237,7 +237,7 @@ func caller9b() { ...@@ -237,7 +237,7 @@ func caller9b() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
p := &i // ERROR "moved to heap: p$" p := &i // ERROR "moved to heap: p$"
p2 := &p p2 := &p
sink = param9(&p2) // ERROR "param9\(&p2\) escapes to heap" sink = param9(&p2)
} }
// **in -> out // **in -> out
...@@ -256,7 +256,7 @@ func caller10b() { ...@@ -256,7 +256,7 @@ func caller10b() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
p := &i p := &i
p2 := &p p2 := &p
sink = param10(&p2) // ERROR "param10\(&p2\) escapes to heap" sink = param10(&p2)
} }
// in escapes to heap (address of param taken and returned) // in escapes to heap (address of param taken and returned)
...@@ -273,20 +273,20 @@ func caller11a() { ...@@ -273,20 +273,20 @@ func caller11a() {
func caller11b() { func caller11b() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
p := &i // ERROR "moved to heap: p$" p := &i // ERROR "moved to heap: p$"
sink = param11(&p) // ERROR "param11\(&p\) escapes to heap" sink = param11(&p)
} }
func caller11c() { // GOOD func caller11c() { // GOOD
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
p := &i // ERROR "moved to heap: p" p := &i // ERROR "moved to heap: p"
sink = *param11(&p) // ERROR "\*param11\(&p\) escapes to heap" sink = *param11(&p)
} }
func caller11d() { func caller11d() {
i := 0 // ERROR "moved to heap: i$" i := 0 // ERROR "moved to heap: i$"
p := &i // ERROR "moved to heap: p" p := &i // ERROR "moved to heap: p"
p2 := &p p2 := &p
sink = param11(p2) // ERROR "param11\(p2\) escapes to heap" sink = param11(p2)
} }
// &in -> rcvr // &in -> rcvr
...@@ -319,7 +319,7 @@ func caller12c() { ...@@ -319,7 +319,7 @@ func caller12c() {
p := &i // ERROR "moved to heap: p$" p := &i // ERROR "moved to heap: p$"
r := Indir{} r := Indir{}
r.param12(&p) r.param12(&p)
sink = r // ERROR "r escapes to heap$" sink = r
} }
func caller12d() { func caller12d() {
...@@ -327,7 +327,7 @@ func caller12d() { ...@@ -327,7 +327,7 @@ func caller12d() {
p := &i // ERROR "moved to heap: p$" p := &i // ERROR "moved to heap: p$"
r := Indir{} r := Indir{}
r.param12(&p) r.param12(&p)
sink = **r.p // ERROR "\* \(\*r\.p\) escapes to heap" sink = **r.p
} }
// in -> value rcvr // in -> value rcvr
...@@ -370,7 +370,7 @@ func caller13d() { ...@@ -370,7 +370,7 @@ func caller13d() {
var v Val var v Val
v.p = &p v.p = &p
v.param13(&i) v.param13(&i)
sink = v // ERROR "v escapes to heap$" sink = v
} }
func caller13e() { func caller13e() {
...@@ -378,7 +378,7 @@ func caller13e() { ...@@ -378,7 +378,7 @@ func caller13e() {
var p *int // ERROR "moved to heap: p$" var p *int // ERROR "moved to heap: p$"
v := Val{&p} v := Val{&p}
v.param13(&i) v.param13(&i)
sink = v // ERROR "v escapes to heap$" sink = v
} }
func caller13f() { func caller13f() {
...@@ -386,7 +386,7 @@ func caller13f() { ...@@ -386,7 +386,7 @@ func caller13f() {
var p *int // ERROR "moved to heap: p$" var p *int // ERROR "moved to heap: p$"
v := &Val{&p} // ERROR "&Val literal escapes to heap$" v := &Val{&p} // ERROR "&Val literal escapes to heap$"
v.param13(&i) v.param13(&i)
sink = v // ERROR "v escapes to heap$" sink = v
} }
func caller13g() { func caller13g() {
...@@ -394,7 +394,7 @@ func caller13g() { ...@@ -394,7 +394,7 @@ func caller13g() {
var p *int var p *int
v := Val{&p} v := Val{&p}
v.param13(&i) v.param13(&i)
sink = *v.p // ERROR "\*v\.p escapes to heap" sink = *v.p
} }
func caller13h() { func caller13h() {
...@@ -437,5 +437,5 @@ func param14a(x [4]*int) interface{} { // ERROR "leaking param: x$" ...@@ -437,5 +437,5 @@ func param14a(x [4]*int) interface{} { // ERROR "leaking param: x$"
// Convert to a direct interface, does not need an allocation. // Convert to a direct interface, does not need an allocation.
// So x only leaks to result. // So x only leaks to result.
func param14b(x *int) interface{} { // ERROR "leaking param: x to result ~r1 level=0" func param14b(x *int) interface{} { // ERROR "leaking param: x to result ~r1 level=0"
return x // ERROR "x escapes to heap" return x
} }
...@@ -41,12 +41,12 @@ func arithMask() unsafe.Pointer { ...@@ -41,12 +41,12 @@ func arithMask() unsafe.Pointer {
// BAD: should be "leaking param: p to result ~r1 level=0$" // BAD: should be "leaking param: p to result ~r1 level=0$"
func valuePointer(p *int) unsafe.Pointer { // ERROR "leaking param: p$" func valuePointer(p *int) unsafe.Pointer { // ERROR "leaking param: p$"
return unsafe.Pointer(reflect.ValueOf(p).Pointer()) // ERROR "p escapes to heap" return unsafe.Pointer(reflect.ValueOf(p).Pointer())
} }
// BAD: should be "leaking param: p to result ~r1 level=0$" // BAD: should be "leaking param: p to result ~r1 level=0$"
func valueUnsafeAddr(p *int) unsafe.Pointer { // ERROR "leaking param: p$" func valueUnsafeAddr(p *int) unsafe.Pointer { // ERROR "leaking param: p$"
return unsafe.Pointer(reflect.ValueOf(p).Elem().UnsafeAddr()) // ERROR "p escapes to heap" return unsafe.Pointer(reflect.ValueOf(p).Elem().UnsafeAddr())
} }
// (6) Conversion of a reflect.SliceHeader or reflect.StringHeader // (6) Conversion of a reflect.SliceHeader or reflect.StringHeader
......
...@@ -84,7 +84,7 @@ func TFooI() { ...@@ -84,7 +84,7 @@ func TFooI() {
a := int32(1) // ERROR "moved to heap: a" a := int32(1) // ERROR "moved to heap: a"
b := "cat" b := "cat"
c := &a c := &a
FooI(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooI ... argument does not escape" FooI(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "TFooI ... argument does not escape"
} }
func FooJ(args ...interface{}) *int32 { // ERROR "leaking param: args to result ~r1 level=1" func FooJ(args ...interface{}) *int32 { // ERROR "leaking param: args to result ~r1 level=1"
...@@ -108,14 +108,14 @@ func TFooJ1() { ...@@ -108,14 +108,14 @@ func TFooJ1() {
a := int32(1) a := int32(1)
b := "cat" b := "cat"
c := &a c := &a
FooJ(a, b, c) // ERROR "TFooJ1 a does not escape" "TFooJ1 b does not escape" "TFooJ1 c does not escape" "TFooJ1 ... argument does not escape" FooJ(a, b, c) // ERROR "TFooJ1 a does not escape" "TFooJ1 b does not escape" "TFooJ1 ... argument does not escape"
} }
func TFooJ2() { func TFooJ2() {
a := int32(1) // ERROR "moved to heap: a" a := int32(1) // ERROR "moved to heap: a"
b := "cat" b := "cat"
c := &a c := &a
isink = FooJ(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooJ2 ... argument does not escape" isink = FooJ(a, b, c) // ERROR "a escapes to heap" "b escapes to heap" "TFooJ2 ... argument does not escape"
} }
type fakeSlice struct { type fakeSlice struct {
...@@ -144,7 +144,7 @@ func TFooK2() { ...@@ -144,7 +144,7 @@ func TFooK2() {
a := int32(1) // ERROR "moved to heap: a" a := int32(1) // ERROR "moved to heap: a"
b := "cat" b := "cat"
c := &a c := &a
fs := fakeSlice{3, &[4]interface{}{a, b, c, nil}} // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooK2 &\[4\]interface {} literal does not escape" fs := fakeSlice{3, &[4]interface{}{a, b, c, nil}} // ERROR "a escapes to heap" "b escapes to heap" "TFooK2 &\[4\]interface {} literal does not escape"
isink = FooK(fs) isink = FooK(fs)
} }
...@@ -169,6 +169,6 @@ func TFooL2() { ...@@ -169,6 +169,6 @@ func TFooL2() {
a := int32(1) // ERROR "moved to heap: a" a := int32(1) // ERROR "moved to heap: a"
b := "cat" b := "cat"
c := &a c := &a
s := []interface{}{a, b, c} // ERROR "a escapes to heap" "b escapes to heap" "c escapes to heap" "TFooL2 \[\]interface {} literal does not escape" s := []interface{}{a, b, c} // ERROR "a escapes to heap" "b escapes to heap" "TFooL2 \[\]interface {} literal does not escape"
isink = FooL(s) isink = FooL(s)
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment