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)
}
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
}
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() {
}
func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
- m = mv1 // ERROR "mv1 escapes to heap$"
+ m = mv1
foo64(m)
}
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
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
}
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() {
}
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$"
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)
}
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)
}
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
}()
}
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
}()
}
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
}
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
}
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
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
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]
}
y byte
}
}
- t := new(T) // ERROR "new\(T\) escapes to heap$"
+ t := new(T) // ERROR "new\(T\) escapes to heap$"
return &t.x.y
}
}
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])
}
}
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])
}
}
func foo152() {
- a := "a" // ERROR "moved to heap: a$"
+ a := "a" // ERROR "moved to heap: a$"
u := U{&a}
v := NewV(u)
println(v)
}
func g() (x interface{}) { // ERROR "moved to heap: x$"
- x = &x // ERROR "&x escapes to heap$"
+ x = &x
return
}
// 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
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$"
// 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$"
}
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() {
// 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() {
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$"
}
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
}
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() {
}
func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
- m = mv1 // ERROR "mv1 escapes to heap$"
+ m = mv1
foo64(m)
}
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
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
}
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() {
}
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$"
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)
}
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)
}
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
}()
}
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
}()
}
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
}
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
}
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
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
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]
}
y byte
}
}
- t := new(T) // ERROR "new\(T\) escapes to heap$"
+ t := new(T) // ERROR "new\(T\) escapes to heap$"
return &t.x.y
}
}
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])
}
}
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])
}
}
func foo152() {
- a := "a" // ERROR "moved to heap: a$"
+ a := "a" // ERROR "moved to heap: a$"
u := U{&a}
v := NewV(u)
println(v)
}
func g() (x interface{}) { // ERROR "moved to heap: x$"
- x = &x // ERROR "&x escapes to heap$"
+ x = &x
return
}
// 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
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$"
// 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$"
}
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() {
// 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() {
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$"
}
// should make p leak always
- global = p // ERROR "p escapes to heap"
+ global = p
return T2{p}
}
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).
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)
}
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)
}
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)
}
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)
}
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)
}
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)
}
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() {
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() {
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() {
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() {
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() {
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() {
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() {
}
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"
{
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
}
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)
}
}
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
{
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
}
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)
}
}
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)
}
}
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() {
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
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() {
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() {
p0 := &i // ERROR "moved to heap: p0"
p1 := &p0
p2 := &p1
- sink = *p2 // ERROR "\*p2 escapes to heap"
+ sink = *p2
}
func level3() {
p0 := &i
p1 := &p0
p2 := &p1
- sink = **p2 // ERROR "\* \(\*p2\) escapes to heap"
+ sink = **p2
}
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() {
p0 := &i // ERROR "moved to heap: p0"
p1 := &p0
p2 := p1
- sink = p2 // ERROR "p2 escapes to heap"
+ sink = p2
}
func level6() {
p0 := &i
p1 := &p0
p2 := p1
- sink = *p2 // ERROR "\*p2 escapes to heap"
+ sink = *p2
}
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() {
p0 := &i
p1 := &p0
p2 := *p1
- sink = p2 // ERROR "p2 escapes to heap"
+ sink = p2
}
func level9() {
p0 := &i
p1 := &p0
p2 := **p1 // ERROR "moved to heap: p2"
- sink = &p2 // ERROR "&p2 escapes to heap"
+ sink = &p2
}
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 {
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
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"
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"
// in -> heap
func param5(i *int) { // ERROR "leaking param: i$"
- sink = i // ERROR "i escapes to heap$"
+ sink = i
}
func caller5() {
// *in -> heap
func param6(i ***int) { // ERROR "leaking param content: i$"
- sink = *i // ERROR "\*i escapes to heap$"
+ sink = *i
}
func caller6a() {
// **in -> heap
func param7(i ***int) { // ERROR "leaking param content: i$"
- sink = **i // ERROR "\* \(\*i\) escapes to heap"
+ sink = **i
}
func caller7() {
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
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)
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
p := &i // ERROR "moved to heap: p$"
r := Indir{}
r.param12(&p)
- sink = r // ERROR "r escapes to heap$"
+ sink = r
}
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
var v Val
v.p = &p
v.param13(&i)
- sink = v // ERROR "v escapes to heap$"
+ sink = v
}
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() {
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() {
var p *int
v := Val{&p}
v.param13(&i)
- sink = *v.p // ERROR "\*v\.p escapes to heap"
+ sink = *v.p
}
func caller13h() {
// 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
}
// 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
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"
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 {
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)
}
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)
}