1
0
mirror of https://github.com/golang/go synced 2024-07-01 07:56:09 +00:00

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: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Matthew Dempsky 2019-08-30 10:56:30 -07:00
parent a71967e4c5
commit 9f89edcd96
13 changed files with 172 additions and 179 deletions

View File

@ -484,13 +484,6 @@ func (e *Escape) exprSkipInit(k EscHole, n *Node) {
case OCONVIFACE:
if !n.Left.Type.IsInterface() && !isdirectiface(n.Left.Type) {
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)

View File

@ -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$"
v := 0 // ERROR "moved to heap: v$"
v := 0 // ERROR "moved to heap: v$"
b.ii = &v
return b.ii
}
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
return b.ii
}
@ -465,12 +465,12 @@ func (MV) M() {}
func foo65() {
var mv MV
foo63(&mv) // ERROR "foo65 &mv does not escape$"
foo63(&mv)
}
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)
}
func foo67() {
@ -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$"
m = mv1 // ERROR "mv1 escapes to heap$"
m = mv1
foo64(m)
}
@ -522,7 +522,7 @@ func foo72a() {
var y [10]*int
for i := 0; i < 10; i++ {
// escapes its scope
x := i // ERROR "moved to heap: x$"
x := i // ERROR "moved to heap: x$"
y[i] = &x
}
return
@ -531,7 +531,7 @@ func foo72a() {
func foo72b() [10]*int {
var y [10]*int
for i := 0; i < 10; i++ {
x := i // ERROR "moved to heap: x$"
x := i // ERROR "moved to heap: x$"
y[i] = &x
}
return y
@ -637,15 +637,15 @@ func foo75aesc(z *int) { // ERROR "foo75aesc 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"
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"
myprint1(nil, z) // ERROR "foo76a ... argument does not escape$" "z does not escape"
myprint1(nil, z) // ERROR "foo76a ... argument does not escape$"
}
func foo76b() {
@ -691,15 +691,15 @@ func foo77b(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() {
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
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$"
@ -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 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(&x, &y)
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(&v, &w)
}
@ -916,22 +916,22 @@ func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
func foo116(b bool) *int {
if b {
x := 1 // ERROR "moved to heap: x$"
x := 1 // ERROR "moved to heap: x$"
return &x
} else {
y := 1 // ERROR "moved to heap: y$"
y := 1 // ERROR "moved to heap: y$"
return &y
}
return nil
}
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$"
x := 1 // ERROR "moved to heap: x$"
unknown(&x)
}
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)
}
@ -1185,7 +1185,7 @@ L1:
func foo124(x **int) { // ERROR "foo124 x does not escape$"
var i int // ERROR "moved to heap: i$"
p := &i
func() { // ERROR "foo124 func literal does not escape$"
func() { // ERROR "foo124 func literal does not escape$"
*x = p
}()
}
@ -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$"
var i int // ERROR "moved to heap: i$"
p := &i
func() { // ERROR "foo125 func literal does not escape$"
func() { // ERROR "foo125 func literal does not escape$"
ch <- p
}()
}
@ -1229,7 +1229,7 @@ func foo128() {
func foo129() {
var i int // ERROR "moved to heap: i$"
p := &i
func() { // ERROR "foo129 func literal does not escape$"
func() { // ERROR "foo129 func literal does not escape$"
q := p
func() { // ERROR "foo129.func1 func literal does not escape$"
r := q
@ -1281,7 +1281,7 @@ func foo134() {
}
func foo135() {
var i int // ERROR "moved to heap: i$"
var i int // ERROR "moved to heap: i$"
p := &i
go func() { // ERROR "func literal escapes to heap$"
q := p
@ -1293,7 +1293,7 @@ func foo135() {
}
func foo136() {
var i int // ERROR "moved to heap: i$"
var i int // ERROR "moved to heap: i$"
p := &i
go func() { // ERROR "func literal escapes to heap$"
q := p
@ -1307,7 +1307,7 @@ func foo136() {
func foo137() {
var i int // ERROR "moved to heap: i$"
p := &i
func() { // ERROR "foo137 func literal does not escape$"
func() { // ERROR "foo137 func literal does not escape$"
q := p
go func() { // ERROR "func literal escapes to heap$"
r := q
@ -1320,7 +1320,7 @@ func foo138() *byte {
type T struct {
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]
}
@ -1330,7 +1330,7 @@ func foo139() *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
}
@ -1498,7 +1498,7 @@ func bar151() {
}
func bar151b() {
var a [10]int // ERROR "moved to heap: a$"
var a [10]int // ERROR "moved to heap: a$"
b := a[:]
foo151(&b[4:8][0])
}
@ -1510,7 +1510,7 @@ func bar151c() {
}
func bar151d() {
var a [10]int // ERROR "moved to heap: a$"
var a [10]int // ERROR "moved to heap: a$"
b := a[:]
foo151(&b[4:8:8][0])
}
@ -1534,7 +1534,7 @@ func NewV(u U) *V { // ERROR "leaking param: u$"
}
func foo152() {
a := "a" // ERROR "moved to heap: a$"
a := "a" // ERROR "moved to heap: a$"
u := U{&a}
v := NewV(u)
println(v)
@ -1558,7 +1558,7 @@ func f() (x int, y *int) { // ERROR "moved to heap: x$"
}
func g() (x interface{}) { // ERROR "moved to heap: x$"
x = &x // ERROR "&x escapes to heap$"
x = &x
return
}
@ -1579,14 +1579,14 @@ func ptrlitNoEscape2() {
// Literal does not escape, but element does.
i := 0 // ERROR "moved to heap: i$"
x := &Lit{&i} // ERROR "ptrlitNoEscape2 &Lit literal does not escape$"
sink = *x // ERROR "\*x escapes to heap$"
sink = *x
}
func ptrlitEscape() {
// Both literal and element escape.
i := 0 // ERROR "moved to heap: i$"
x := &Lit{&i} // ERROR "&Lit literal escapes to heap$"
sink = x // ERROR "x escapes to heap$"
sink = x
}
// self-assignments
@ -1624,7 +1624,7 @@ func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
func (b *Buffer) bat() { // ERROR "leaking param content: b$"
o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
o.buf1 = b.buf1[1:2]
sink = o // ERROR "o escapes to heap$"
sink = o
}
func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
@ -1642,7 +1642,7 @@ type StructWithString struct {
// to just x, and thus &i looks escaping.
func fieldFlowTracking() {
var x StructWithString
i := 0 // ERROR "moved to heap: i$"
i := 0 // ERROR "moved to heap: i$"
x.p = &i
sink = x.s // ERROR "x.s escapes to heap$"
}
@ -1666,7 +1666,7 @@ func slicebytetostring2() {
b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$"
s := string(b) // ERROR "string\(b\) escapes to heap$"
s1 := s[0:1] // ERROR "moved to heap: s1$"
sink = &s1 // ERROR "&s1 escapes to heap$"
sink = &s1
}
func slicebytetostring3() {
@ -1724,7 +1724,7 @@ func intstring2() {
// string escapes to heap
x := '0'
s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
sink = &s // ERROR "&s escapes to heap$"
sink = &s
}
func stringtoslicebyte0() {
@ -1789,7 +1789,7 @@ func makemap1() map[int]int {
func makemap2() {
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$"

View File

@ -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$"
v := 0 // ERROR "moved to heap: v$"
v := 0 // ERROR "moved to heap: v$"
b.ii = &v
return b.ii
}
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
return b.ii
}
@ -465,12 +465,12 @@ func (MV) M() {}
func foo65() {
var mv MV
foo63(&mv) // ERROR "foo65 &mv does not escape$"
foo63(&mv)
}
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)
}
func foo67() {
@ -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$"
m = mv1 // ERROR "mv1 escapes to heap$"
m = mv1
foo64(m)
}
@ -522,7 +522,7 @@ func foo72a() {
var y [10]*int
for i := 0; i < 10; i++ {
// escapes its scope
x := i // ERROR "moved to heap: x$"
x := i // ERROR "moved to heap: x$"
y[i] = &x
}
return
@ -531,7 +531,7 @@ func foo72a() {
func foo72b() [10]*int {
var y [10]*int
for i := 0; i < 10; i++ {
x := i // ERROR "moved to heap: x$"
x := i // ERROR "moved to heap: x$"
y[i] = &x
}
return y
@ -637,15 +637,15 @@ func foo75aesc(z *int) { // ERROR "foo75aesc 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"
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"
myprint1(nil, z) // ERROR "foo76a ... argument does not escape$" "z does not escape"
myprint1(nil, z) // ERROR "foo76a ... argument does not escape$"
}
func foo76b() {
@ -691,15 +691,15 @@ func foo77b(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() {
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
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$"
@ -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 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(&x, &y)
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(&v, &w)
}
@ -916,22 +916,22 @@ func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
func foo116(b bool) *int {
if b {
x := 1 // ERROR "moved to heap: x$"
x := 1 // ERROR "moved to heap: x$"
return &x
} else {
y := 1 // ERROR "moved to heap: y$"
y := 1 // ERROR "moved to heap: y$"
return &y
}
return nil
}
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$"
x := 1 // ERROR "moved to heap: x$"
unknown(&x)
}
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)
}
@ -1185,7 +1185,7 @@ L1:
func foo124(x **int) { // ERROR "foo124 x does not escape$"
var i int // ERROR "moved to heap: i$"
p := &i
func() { // ERROR "foo124 func literal does not escape$"
func() { // ERROR "foo124 func literal does not escape$"
*x = p
}()
}
@ -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$"
var i int // ERROR "moved to heap: i$"
p := &i
func() { // ERROR "foo125 func literal does not escape$"
func() { // ERROR "foo125 func literal does not escape$"
ch <- p
}()
}
@ -1229,7 +1229,7 @@ func foo128() {
func foo129() {
var i int // ERROR "moved to heap: i$"
p := &i
func() { // ERROR "foo129 func literal does not escape$"
func() { // ERROR "foo129 func literal does not escape$"
q := p
func() { // ERROR "foo129.func1 func literal does not escape$"
r := q
@ -1281,7 +1281,7 @@ func foo134() {
}
func foo135() {
var i int // ERROR "moved to heap: i$"
var i int // ERROR "moved to heap: i$"
p := &i
go func() { // ERROR "func literal escapes to heap$"
q := p
@ -1293,7 +1293,7 @@ func foo135() {
}
func foo136() {
var i int // ERROR "moved to heap: i$"
var i int // ERROR "moved to heap: i$"
p := &i
go func() { // ERROR "func literal escapes to heap$"
q := p
@ -1307,7 +1307,7 @@ func foo136() {
func foo137() {
var i int // ERROR "moved to heap: i$"
p := &i
func() { // ERROR "foo137 func literal does not escape$"
func() { // ERROR "foo137 func literal does not escape$"
q := p
go func() { // ERROR "func literal escapes to heap$"
r := q
@ -1320,7 +1320,7 @@ func foo138() *byte {
type T struct {
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]
}
@ -1330,7 +1330,7 @@ func foo139() *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
}
@ -1498,7 +1498,7 @@ func bar151() {
}
func bar151b() {
var a [10]int // ERROR "moved to heap: a$"
var a [10]int // ERROR "moved to heap: a$"
b := a[:]
foo151(&b[4:8][0])
}
@ -1510,7 +1510,7 @@ func bar151c() {
}
func bar151d() {
var a [10]int // ERROR "moved to heap: a$"
var a [10]int // ERROR "moved to heap: a$"
b := a[:]
foo151(&b[4:8:8][0])
}
@ -1534,7 +1534,7 @@ func NewV(u U) *V { // ERROR "leaking param: u$"
}
func foo152() {
a := "a" // ERROR "moved to heap: a$"
a := "a" // ERROR "moved to heap: a$"
u := U{&a}
v := NewV(u)
println(v)
@ -1558,7 +1558,7 @@ func f() (x int, y *int) { // ERROR "moved to heap: x$"
}
func g() (x interface{}) { // ERROR "moved to heap: x$"
x = &x // ERROR "&x escapes to heap$"
x = &x
return
}
@ -1579,14 +1579,14 @@ func ptrlitNoEscape2() {
// Literal does not escape, but element does.
i := 0 // ERROR "moved to heap: i$"
x := &Lit{&i} // ERROR "ptrlitNoEscape2 &Lit literal does not escape$"
sink = *x // ERROR "\*x escapes to heap$"
sink = *x
}
func ptrlitEscape() {
// Both literal and element escape.
i := 0 // ERROR "moved to heap: i$"
x := &Lit{&i} // ERROR "&Lit literal escapes to heap$"
sink = x // ERROR "x escapes to heap$"
sink = x
}
// self-assignments
@ -1624,7 +1624,7 @@ func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
func (b *Buffer) bat() { // ERROR "leaking param content: b$"
o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
o.buf1 = b.buf1[1:2]
sink = o // ERROR "o escapes to heap$"
sink = o
}
func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
@ -1642,7 +1642,7 @@ type StructWithString struct {
// to just x, and thus &i looks escaping.
func fieldFlowTracking() {
var x StructWithString
i := 0 // ERROR "moved to heap: i$"
i := 0 // ERROR "moved to heap: i$"
x.p = &i
sink = x.s // ERROR "x.s escapes to heap$"
}
@ -1666,7 +1666,7 @@ func slicebytetostring2() {
b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$"
s := string(b) // ERROR "string\(b\) escapes to heap$"
s1 := s[0:1] // ERROR "moved to heap: s1$"
sink = &s1 // ERROR "&s1 escapes to heap$"
sink = &s1
}
func slicebytetostring3() {
@ -1724,7 +1724,7 @@ func intstring2() {
// string escapes to heap
x := '0'
s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
sink = &s // ERROR "&s escapes to heap$"
sink = &s
}
func stringtoslicebyte0() {
@ -1789,7 +1789,7 @@ func makemap1() map[int]int {
func makemap2() {
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$"

View File

@ -139,7 +139,7 @@ func f8(p *T1) (k T2) { // ERROR "leaking param: p$"
}
// should make p leak always
global = p // ERROR "p escapes to heap"
global = p
return T2{p}
}
@ -164,7 +164,7 @@ func f13() {
var x *int
f11(&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).

View File

@ -38,7 +38,7 @@ func ClosureCallArgs2() {
func ClosureCallArgs3() {
x := 0 // ERROR "moved to heap: x"
func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
sink = p // ERROR "p escapes to heap"
sink = p
}(&x)
}
@ -53,7 +53,7 @@ func ClosureCallArgs5() {
x := 0 // ERROR "moved to heap: x"
// 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.
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
}(&x)
}
@ -61,7 +61,7 @@ func ClosureCallArgs5() {
func ClosureCallArgs6() {
x := 0 // ERROR "moved to heap: x"
func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
sink = &p // ERROR "&p escapes to heap"
sink = &p
}(&x)
}
@ -105,7 +105,7 @@ func ClosureCallArgs10() {
func ClosureCallArgs11() {
x := 0 // ERROR "moved to heap: x"
defer func(p *int) { // ERROR "leaking param: p" "func literal does not escape"
sink = p // ERROR "p escapes to heap"
sink = p
}(&x)
}
@ -119,7 +119,7 @@ func ClosureCallArgs12() {
func ClosureCallArgs13() {
x := 0 // ERROR "moved to heap: x"
defer func(p *int) { // ERROR "moved to heap: p" "func literal does not escape"
sink = &p // ERROR "&p escapes to heap"
sink = &p
}(&x)
}
@ -134,7 +134,7 @@ func ClosureCallArgs14() {
func ClosureCallArgs15() {
x := 0 // ERROR "moved to heap: 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
}(&p)
}

View File

@ -24,7 +24,7 @@ func field0() {
i := 0 // ERROR "moved to heap: i$"
var x X
x.p1 = &i
sink = x.p1 // ERROR "x\.p1 escapes to heap"
sink = x.p1
}
func field1() {
@ -32,14 +32,14 @@ func field1() {
var x X
// BAD: &i should not escape
x.p1 = &i
sink = x.p2 // ERROR "x\.p2 escapes to heap"
sink = x.p2
}
func field3() {
i := 0 // ERROR "moved to heap: i$"
var x X
x.p1 = &i
sink = x // ERROR "x escapes to heap"
sink = x // ERROR "x escapes to heap"
}
func field4() {
@ -55,12 +55,12 @@ func field5() {
var x X
// BAD: &i should not escape here
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
func field6(x *X) { // ERROR "leaking param content: x$"
sink = x.p2 // ERROR "x\.p2 escapes to heap"
sink = x.p2
}
func field6a() {
@ -88,7 +88,7 @@ func field8() {
x := y.x
var y1 Y
y1.x = x
sink = y1.x.p1 // ERROR "y1\.x\.p1 escapes to heap"
sink = y1.x.p1
}
func field9() {
@ -109,39 +109,39 @@ func field10() {
x := y.x
var y1 Y
y1.x = x
sink = y1.x.p2 // ERROR "y1\.x\.p2 escapes to heap"
sink = y1.x.p2
}
func field11() {
i := 0 // ERROR "moved to heap: i$"
i := 0 // ERROR "moved to heap: i$"
x := X{p1: &i}
sink = x.p1 // ERROR "x\.p1 escapes to heap"
sink = x.p1
}
func field12() {
i := 0 // ERROR "moved to heap: i$"
// BAD: &i should not escape
x := X{p1: &i}
sink = x.p2 // ERROR "x\.p2 escapes to heap"
sink = x.p2
}
func field13() {
i := 0 // ERROR "moved to heap: i$"
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() {
i := 0 // ERROR "moved to heap: i$"
// BAD: &i should 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() {
i := 0 // ERROR "moved to heap: i$"
x := &X{p1: &i} // ERROR "&X literal escapes to heap$"
sink = x // ERROR "x escapes to heap"
sink = x
}
func field16() {
@ -151,7 +151,7 @@ func field16() {
x.p1 = &i
var iface interface{} = x // ERROR "field16 x does not escape"
x1 := iface.(X)
sink = x1.p2 // ERROR "x1\.p2 escapes to heap"
sink = x1.p2
}
func field17() {
@ -160,7 +160,7 @@ func field17() {
x.p1 = &i
var iface interface{} = x // ERROR "field17 x does not escape"
x1 := iface.(X)
sink = x1.p1 // ERROR "x1\.p1 escapes to heap"
sink = x1.p1
}
func field18() {

View File

@ -15,7 +15,7 @@ type M interface {
}
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"
@ -33,19 +33,19 @@ func efaceEscape0() {
{
i := 0
v := M0{&i}
var x M = v // ERROR "v does not escape"
var x M = v
_ = x
}
{
i := 0 // ERROR "moved to heap: i"
v := M0{&i}
var x M = v // ERROR "v escapes to heap"
sink = x // ERROR "x escapes to heap"
var x M = v
sink = x
}
{
i := 0
v := M0{&i}
var x M = v // ERROR "v does not escape"
var x M = v
v1 := x.(M0)
_ = v1
}
@ -53,27 +53,27 @@ func efaceEscape0() {
i := 0 // ERROR "moved to heap: i"
v := M0{&i}
// BAD: v does not escape to heap here
var x M = v // ERROR "v escapes to heap"
var x M = v
v1 := x.(M0)
sink = v1 // ERROR "v1 escapes to heap"
sink = v1
}
{
i := 0 // ERROR "moved to heap: i"
v := M0{&i}
// BAD: v does not escape to heap here
var x M = v // ERROR "v escapes to heap"
var x M = v
x.M()
}
{
i := 0 // ERROR "moved to heap: i"
v := M0{&i}
var x M = v // ERROR "v escapes to heap"
var x M = v
mescapes(x)
}
{
i := 0
v := M0{&i}
var x M = v // ERROR "v does not escape"
var x M = v
mdoesnotescape(x)
}
}
@ -98,7 +98,7 @@ func efaceEscape1() {
i := 0 // ERROR "moved to heap: i"
v := M1{&i, 0}
var x M = v // ERROR "v escapes to heap"
sink = x // ERROR "x escapes to heap"
sink = x
}
{
i := 0
@ -147,19 +147,19 @@ func efaceEscape2() {
{
i := 0
v := &M2{&i} // ERROR "&M2 literal does not escape"
var x M = v // ERROR "v does not escape"
var x M = v
_ = x
}
{
i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal escapes to heap"
var x M = v // ERROR "v escapes to heap"
sink = x // ERROR "x escapes to heap"
var x M = v
sink = x
}
{
i := 0
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
}
@ -167,44 +167,44 @@ func efaceEscape2() {
i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal escapes to heap"
// BAD: v does not escape to heap here
var x M = v // ERROR "v escapes to heap"
var x M = v
v1 := x.(*M2)
sink = v1 // ERROR "v1 escapes to heap"
sink = v1
}
{
i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal does not escape"
// BAD: v does not escape to heap here
var x M = v // ERROR "v does not escape"
var x M = v
v1 := x.(*M2)
sink = *v1 // ERROR "v1 escapes to heap"
sink = *v1
}
{
i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal does not escape"
// 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)
sink = *v1 // ERROR "v1 escapes to heap"
sink = *v1
_ = ok
}
{
i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal escapes to heap"
// BAD: v does not escape to heap here
var x M = v // ERROR "v escapes to heap"
var x M = v
x.M()
}
{
i := 0 // ERROR "moved to heap: i"
v := &M2{&i} // ERROR "&M2 literal escapes to heap"
var x M = v // ERROR "v escapes to heap"
var x M = v
mescapes(x)
}
{
i := 0
v := &M2{&i} // ERROR "&M2 literal does not escape"
var x M = v // ERROR "v does not escape"
var x M = v
mdoesnotescape(x)
}
}
@ -251,10 +251,10 @@ func dotTypeEscape2() { // #13805, #15796
i := 0 // ERROR "moved to heap: i"
j := 0 // ERROR "moved to heap: j"
var ok bool
var x interface{} = &i // ERROR "&i escapes to heap"
var y interface{} = &j // ERROR "&j escapes to heap"
var x interface{} = &i
var y interface{} = &j
sink = x.(*int) // ERROR "x.\(\*int\) escapes to heap"
sink = x.(*int)
sink, *(&ok) = y.(*int)
}
}

View File

@ -54,7 +54,7 @@ func constptr1() {
i := 0 // ERROR "moved to heap: i"
x := &ConstPtr{} // ERROR "&ConstPtr literal escapes to heap"
x.p = &i
sink = x // ERROR "x escapes to heap"
sink = x
}
func constptr2() {
@ -144,7 +144,7 @@ func foo2() {
f **int
}
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
z.f = &x
p := z.f

View File

@ -15,7 +15,7 @@ func level0() {
p0 := &i // ERROR "moved to heap: p0"
p1 := &p0 // ERROR "moved to heap: p1"
p2 := &p1 // ERROR "moved to heap: p2"
sink = &p2 // ERROR "&p2 escapes to heap"
sink = &p2
}
func level1() {
@ -23,7 +23,7 @@ func level1() {
p0 := &i // ERROR "moved to heap: p0"
p1 := &p0 // ERROR "moved to heap: p1"
p2 := &p1
sink = p2 // ERROR "p2 escapes to heap"
sink = p2
}
func level2() {
@ -31,7 +31,7 @@ func level2() {
p0 := &i // ERROR "moved to heap: p0"
p1 := &p0
p2 := &p1
sink = *p2 // ERROR "\*p2 escapes to heap"
sink = *p2
}
func level3() {
@ -39,7 +39,7 @@ func level3() {
p0 := &i
p1 := &p0
p2 := &p1
sink = **p2 // ERROR "\* \(\*p2\) escapes to heap"
sink = **p2
}
func level4() {
@ -47,7 +47,7 @@ func level4() {
p0 := &i // ERROR "moved to heap: p0"
p1 := &p0
p2 := p1 // ERROR "moved to heap: p2"
sink = &p2 // ERROR "&p2 escapes to heap"
sink = &p2
}
func level5() {
@ -55,7 +55,7 @@ func level5() {
p0 := &i // ERROR "moved to heap: p0"
p1 := &p0
p2 := p1
sink = p2 // ERROR "p2 escapes to heap"
sink = p2
}
func level6() {
@ -63,7 +63,7 @@ func level6() {
p0 := &i
p1 := &p0
p2 := p1
sink = *p2 // ERROR "\*p2 escapes to heap"
sink = *p2
}
func level7() {
@ -72,7 +72,7 @@ func level7() {
p1 := &p0
// note *p1 == &i
p2 := *p1 // ERROR "moved to heap: p2"
sink = &p2 // ERROR "&p2 escapes to heap"
sink = &p2
}
func level8() {
@ -80,7 +80,7 @@ func level8() {
p0 := &i
p1 := &p0
p2 := *p1
sink = p2 // ERROR "p2 escapes to heap"
sink = p2
}
func level9() {
@ -104,5 +104,5 @@ func level11() {
p0 := &i
p1 := &p0
p2 := **p1 // ERROR "moved to heap: p2"
sink = &p2 // ERROR "&p2 escapes to heap"
sink = &p2
}

View File

@ -95,7 +95,7 @@ func map8() {
i := 0 // ERROR "moved to heap: i"
j := 0 // ERROR "moved to heap: j"
m := map[*int]*int{&i: &j} // ERROR "literal escapes to heap"
sink = m // ERROR "m escapes to heap"
sink = m
}
func map9() *int {

View File

@ -27,7 +27,7 @@ func caller0a() {
func caller0b() {
i := 0 // ERROR "moved to heap: i$"
sink = param0(&i) // ERROR "param0\(&i\) escapes to heap"
sink = param0(&i)
}
// in, in -> out, out
@ -57,7 +57,7 @@ func caller2b() {
i := 0 // ERROR "moved to heap: i$"
var p *int
param2(&i, &p)
sink = p // ERROR "p escapes to heap$"
sink = p
}
func paramArraySelfAssign(p *PairOfPairs) { // ERROR "p does not escape"
@ -88,27 +88,27 @@ func leakParam(x interface{}) { // ERROR "leaking param: x"
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"
sink = box.pair.p2 // ERROR "box.pair.p2 escapes to heap"
sink = box.pair.p2
}
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"
sink = box.pair // ERROR "box.pair escapes to heap"
sink = box.pair
}
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"
leakParam(box.pair.p2) // ERROR "box.pair.p2 escapes to heap"
leakParam(box.pair.p2)
}
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"
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"
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"
@ -178,7 +178,7 @@ func caller4b() {
// in -> heap
func param5(i *int) { // ERROR "leaking param: i$"
sink = i // ERROR "i escapes to heap$"
sink = i
}
func caller5() {
@ -188,7 +188,7 @@ func caller5() {
// *in -> heap
func param6(i ***int) { // ERROR "leaking param content: i$"
sink = *i // ERROR "\*i escapes to heap$"
sink = *i
}
func caller6a() {
@ -200,7 +200,7 @@ func caller6a() {
// **in -> heap
func param7(i ***int) { // ERROR "leaking param content: i$"
sink = **i // ERROR "\* \(\*i\) escapes to heap"
sink = **i
}
func caller7() {
@ -237,7 +237,7 @@ func caller9b() {
i := 0 // ERROR "moved to heap: i$"
p := &i // ERROR "moved to heap: p$"
p2 := &p
sink = param9(&p2) // ERROR "param9\(&p2\) escapes to heap"
sink = param9(&p2)
}
// **in -> out
@ -256,7 +256,7 @@ func caller10b() {
i := 0 // ERROR "moved to heap: i$"
p := &i
p2 := &p
sink = param10(&p2) // ERROR "param10\(&p2\) escapes to heap"
sink = param10(&p2)
}
// in escapes to heap (address of param taken and returned)
@ -273,20 +273,20 @@ func caller11a() {
func caller11b() {
i := 0 // ERROR "moved to heap: i$"
p := &i // ERROR "moved to heap: p$"
sink = param11(&p) // ERROR "param11\(&p\) escapes to heap"
sink = param11(&p)
}
func caller11c() { // GOOD
i := 0 // ERROR "moved to heap: i$"
p := &i // ERROR "moved to heap: p"
sink = *param11(&p) // ERROR "\*param11\(&p\) escapes to heap"
sink = *param11(&p)
}
func caller11d() {
i := 0 // ERROR "moved to heap: i$"
p := &i // ERROR "moved to heap: p"
p2 := &p
sink = param11(p2) // ERROR "param11\(p2\) escapes to heap"
sink = param11(p2)
}
// &in -> rcvr
@ -319,7 +319,7 @@ func caller12c() {
p := &i // ERROR "moved to heap: p$"
r := Indir{}
r.param12(&p)
sink = r // ERROR "r escapes to heap$"
sink = r
}
func caller12d() {
@ -327,7 +327,7 @@ func caller12d() {
p := &i // ERROR "moved to heap: p$"
r := Indir{}
r.param12(&p)
sink = **r.p // ERROR "\* \(\*r\.p\) escapes to heap"
sink = **r.p
}
// in -> value rcvr
@ -370,7 +370,7 @@ func caller13d() {
var v Val
v.p = &p
v.param13(&i)
sink = v // ERROR "v escapes to heap$"
sink = v
}
func caller13e() {
@ -378,7 +378,7 @@ func caller13e() {
var p *int // ERROR "moved to heap: p$"
v := Val{&p}
v.param13(&i)
sink = v // ERROR "v escapes to heap$"
sink = v
}
func caller13f() {
@ -386,7 +386,7 @@ func caller13f() {
var p *int // ERROR "moved to heap: p$"
v := &Val{&p} // ERROR "&Val literal escapes to heap$"
v.param13(&i)
sink = v // ERROR "v escapes to heap$"
sink = v
}
func caller13g() {
@ -394,7 +394,7 @@ func caller13g() {
var p *int
v := Val{&p}
v.param13(&i)
sink = *v.p // ERROR "\*v\.p escapes to heap"
sink = *v.p
}
func caller13h() {
@ -437,5 +437,5 @@ func param14a(x [4]*int) interface{} { // ERROR "leaking param: x$"
// Convert to a direct interface, does not need an allocation.
// So x only leaks to result.
func param14b(x *int) interface{} { // ERROR "leaking param: x to result ~r1 level=0"
return x // ERROR "x escapes to heap"
return x
}

View File

@ -41,12 +41,12 @@ func arithMask() unsafe.Pointer {
// BAD: should be "leaking param: p to result ~r1 level=0$"
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$"
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

View File

@ -84,7 +84,7 @@ func TFooI() {
a := int32(1) // ERROR "moved to heap: a"
b := "cat"
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"
@ -108,14 +108,14 @@ func TFooJ1() {
a := int32(1)
b := "cat"
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() {
a := int32(1) // ERROR "moved to heap: a"
b := "cat"
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 {
@ -144,7 +144,7 @@ func TFooK2() {
a := int32(1) // ERROR "moved to heap: a"
b := "cat"
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)
}
@ -169,6 +169,6 @@ func TFooL2() {
a := int32(1) // ERROR "moved to heap: a"
b := "cat"
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)
}