3 // Copyright 2012 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // Test, using compiler diagnostic flags, that the escape analysis is working.
8 // Compiles but does not run. Inlining is disabled.
14 func noleak(p *int) int { // ERROR "p does not escape"
18 func leaktoret(p *int) *int { // ERROR "leaking param: p to result"
22 func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: p to result ~r2"
26 func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r2" "leaking param: q to result ~r3"
30 func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
31 return leaktoret22(q, p)
34 func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
35 r, s := leaktoret22(q, p)
39 func leaktoret22d(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
40 r, s = leaktoret22(q, p)
44 func leaktoret22e(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
45 r, s = leaktoret22(q, p)
49 func leaktoret22f(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
50 rr, ss := leaktoret22(q, p)
56 func leaktosink(p *int) *int { // ERROR "leaking param: p"
63 p := noleak(&x) // ERROR "&x does not escape"
69 p := leaktoret(&x) // ERROR "&x does not escape"
74 var x int // ERROR "moved to heap: x"
75 p := leaktoret(&x) // ERROR "&x escapes to heap"
80 var x int // ERROR "moved to heap: x"
81 p, q := leaktoret2(&x) // ERROR "&x escapes to heap"
88 leaktoret22(leaktoret2(&x)) // ERROR "&x does not escape"
92 var x int // ERROR "moved to heap: x"
93 px1, px2 := leaktoret22(leaktoret2(&x)) // ERROR "&x escapes to heap"
98 type T struct{ x int }
100 func (t *T) Foo(u int) (*T, bool) { // ERROR "leaking param: t to result"
106 r, _ := new(T).Foo(42) // ERROR "new.T. escapes to heap"
110 func leakrecursive1(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
111 return leakrecursive2(q, p)
114 func leakrecursive2(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
116 return leakrecursive1(q, p)
118 // without this, leakrecursive? are safe for p and q, b/c in fact their graph does not have leaking edges.
122 var global interface{}
132 func f8(p *T1) (k T2) { // ERROR "leaking param: p to result k" "leaking param: p"
138 // should make p leak always
139 global = p // ERROR "p escapes to heap"
144 var j T1 // ERROR "moved to heap: j"
145 f8(&j) // ERROR "&j escapes to heap"
149 // These don't escape but are too big for the stack
150 var x [1 << 30]byte // ERROR "moved to heap: x"
151 var y = make([]byte, 1<<30) // ERROR "make\(\[\]byte, 1 << 30\) escapes to heap"
155 // Test for issue 19687 (passing to unnamed parameters does not escape).
162 f11(&x) // ERROR "&x does not escape"
163 f12(&x) // ERROR "&x does not escape"
164 runtime.KeepAlive(&x) // ERROR "&x does not escape"
167 // Test for issue 24305 (passing to unnamed receivers does not escape).
175 u.M() // ERROR "u does not escape"
176 u.N() // ERROR "u does not escape"
179 // Issue 24730: taking address in a loop causes unnecessary escape
184 func (t *T24730) g() { // ERROR "t does not escape"
185 y := t.x[:] // ERROR "t\.x does not escape"
186 for i := range t.x[:] { // ERROR "t\.x does not escape"
187 y = t.x[:] // ERROR "t\.x does not escape"
192 for i := range t.x[:] { // ERROR "t\.x does not escape"
193 z = &t.x[i] // ERROR "t\.x\[i\] does not escape"
198 // Issue 15730: copy causes unnecessary escape
204 func f15730a(args ...interface{}) { // ERROR "args does not escape"
205 for _, arg := range args {
206 switch a := arg.(type) {
213 func f15730b(args ...interface{}) { // ERROR "args does not escape"
214 for _, arg := range args {
215 switch a := arg.(type) {
222 func f15730c(args ...interface{}) { // ERROR "leaking param content: args"
223 for _, arg := range args {
224 switch a := arg.(type) {
226 // copy pointerful data should cause escape