blob: b1130d3c3c9d3d2fa2e0f2bcbbe55cf270807ca9 [file] [log] [blame]
Russ Cox00d2f912014-09-24 15:20:03 -04001// errorcheck -0 -N -m -l
2
Emmanuel Odeke53fd5222016-04-10 14:32:26 -07003// Copyright 2010 The Go Authors. All rights reserved.
Russ Cox00d2f912014-09-24 15:20:03 -04004// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test, using compiler diagnostic flags, that the escape analysis is working.
8// Compiles but does not run. Inlining is disabled.
9// Registerization is disabled too (-N), which should
10// have no effect on escape analysis.
11
12package foo
13
14import (
15 "fmt"
16 "unsafe"
17)
18
19var gxx *int
20
Dmitry Vyukov76477412015-02-19 22:00:11 +030021func foo1(x int) { // ERROR "moved to heap: x$"
22 gxx = &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -040023}
24
Dmitry Vyukov76477412015-02-19 22:00:11 +030025func foo2(yy *int) { // ERROR "leaking param: yy$"
Russ Cox00d2f912014-09-24 15:20:03 -040026 gxx = yy
27}
28
Dmitry Vyukov76477412015-02-19 22:00:11 +030029func foo3(x int) *int { // ERROR "moved to heap: x$"
30 return &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -040031}
32
33type T *T
34
Dmitry Vyukov76477412015-02-19 22:00:11 +030035func foo3b(t T) { // ERROR "leaking param: t$"
Russ Cox00d2f912014-09-24 15:20:03 -040036 *t = t
37}
38
39// xx isn't going anywhere, so use of yy is ok
Dmitry Vyukov76477412015-02-19 22:00:11 +030040func foo4(xx, yy *int) { // ERROR "foo4 xx does not escape$" "foo4 yy does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -040041 xx = yy
42}
43
44// xx isn't going anywhere, so taking address of yy is ok
Dmitry Vyukov76477412015-02-19 22:00:11 +030045func foo5(xx **int, yy *int) { // ERROR "foo5 xx does not escape$" "foo5 yy does not escape$"
46 xx = &yy // ERROR "foo5 &yy does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -040047}
48
Dmitry Vyukov76477412015-02-19 22:00:11 +030049func foo6(xx **int, yy *int) { // ERROR "foo6 xx does not escape$" "leaking param: yy$"
Russ Cox00d2f912014-09-24 15:20:03 -040050 *xx = yy
51}
52
Dmitry Vyukov76477412015-02-19 22:00:11 +030053func foo7(xx **int, yy *int) { // ERROR "foo7 xx does not escape$" "foo7 yy does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -040054 **xx = *yy
55}
56
Dmitry Vyukov76477412015-02-19 22:00:11 +030057func foo8(xx, yy *int) int { // ERROR "foo8 xx does not escape$" "foo8 yy does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -040058 xx = yy
59 return *xx
60}
61
David Chase7fbb1b32015-03-26 16:36:15 -040062func foo9(xx, yy *int) *int { // ERROR "leaking param: xx to result ~r2 level=0$" "leaking param: yy to result ~r2 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -040063 xx = yy
64 return xx
65}
66
Dmitry Vyukov76477412015-02-19 22:00:11 +030067func foo10(xx, yy *int) { // ERROR "foo10 xx does not escape$" "foo10 yy does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -040068 *xx = *yy
69}
70
71func foo11() int {
72 x, y := 0, 42
Dmitry Vyukov76477412015-02-19 22:00:11 +030073 xx := &x // ERROR "foo11 &x does not escape$"
74 yy := &y // ERROR "foo11 &y does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -040075 *xx = *yy
76 return x
77}
78
79var xxx **int
80
Dmitry Vyukov76477412015-02-19 22:00:11 +030081func foo12(yyy **int) { // ERROR "leaking param: yyy$"
Russ Cox00d2f912014-09-24 15:20:03 -040082 xxx = yyy
83}
84
85// Must treat yyy as leaking because *yyy leaks, and the escape analysis
86// summaries in exported metadata do not distinguish these two cases.
David Chase7fbb1b32015-03-26 16:36:15 -040087func foo13(yyy **int) { // ERROR "leaking param content: yyy$"
Russ Cox00d2f912014-09-24 15:20:03 -040088 *xxx = *yyy
89}
90
Dmitry Vyukov76477412015-02-19 22:00:11 +030091func foo14(yyy **int) { // ERROR "foo14 yyy does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -040092 **xxx = **yyy
93}
94
Dmitry Vyukov76477412015-02-19 22:00:11 +030095func foo15(yy *int) { // ERROR "moved to heap: yy$"
96 xxx = &yy // ERROR "&yy escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -040097}
98
Dmitry Vyukov76477412015-02-19 22:00:11 +030099func foo16(yy *int) { // ERROR "leaking param: yy$"
Russ Cox00d2f912014-09-24 15:20:03 -0400100 *xxx = yy
101}
102
Dmitry Vyukov76477412015-02-19 22:00:11 +0300103func foo17(yy *int) { // ERROR "foo17 yy does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400104 **xxx = *yy
105}
106
Dmitry Vyukov76477412015-02-19 22:00:11 +0300107func foo18(y int) { // ERROR "moved to heap: y$"
108 *xxx = &y // ERROR "&y escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400109}
110
111func foo19(y int) {
112 **xxx = y
113}
114
115type Bar struct {
116 i int
117 ii *int
118}
119
120func NewBar() *Bar {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300121 return &Bar{42, nil} // ERROR "&Bar literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400122}
123
David Chase7fbb1b32015-03-26 16:36:15 -0400124func NewBarp(x *int) *Bar { // ERROR "leaking param: x to result ~r1 level=-1$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300125 return &Bar{42, x} // ERROR "&Bar literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400126}
127
Dmitry Vyukov76477412015-02-19 22:00:11 +0300128func NewBarp2(x *int) *Bar { // ERROR "NewBarp2 x does not escape$"
129 return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400130}
131
Dmitry Vyukov76477412015-02-19 22:00:11 +0300132func (b *Bar) NoLeak() int { // ERROR "\(\*Bar\).NoLeak b does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400133 return *(b.ii)
134}
135
David Chase7fbb1b32015-03-26 16:36:15 -0400136func (b *Bar) Leak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300137 return &b.i // ERROR "&b.i escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400138}
139
David Chase7fbb1b32015-03-26 16:36:15 -0400140func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param: b to result ~r0 level=1$"
Russ Cox00d2f912014-09-24 15:20:03 -0400141 return b.ii
142}
143
David Chase7fbb1b32015-03-26 16:36:15 -0400144func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b to result ~r0 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400145 return b.ii
146}
147
David Chase7fbb1b32015-03-26 16:36:15 -0400148func (b Bar) LeaksToo() *int { // ERROR "leaking param: b to result ~r0 level=0$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300149 v := 0 // ERROR "moved to heap: v$"
150 b.ii = &v // ERROR "&v escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400151 return b.ii
152}
153
David Chase7fbb1b32015-03-26 16:36:15 -0400154func (b *Bar) LeaksABit() *int { // ERROR "leaking param: b to result ~r0 level=1$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300155 v := 0 // ERROR "moved to heap: v$"
156 b.ii = &v // ERROR "&v escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400157 return b.ii
158}
159
Dmitry Vyukov76477412015-02-19 22:00:11 +0300160func (b Bar) StillNoLeak() int { // ERROR "Bar.StillNoLeak b does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400161 v := 0
Dmitry Vyukov76477412015-02-19 22:00:11 +0300162 b.ii = &v // ERROR "Bar.StillNoLeak &v does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400163 return b.i
164}
165
Dmitry Vyukov76477412015-02-19 22:00:11 +0300166func goLeak(b *Bar) { // ERROR "leaking param: b$"
Russ Cox00d2f912014-09-24 15:20:03 -0400167 go b.NoLeak()
168}
169
170type Bar2 struct {
171 i [12]int
172 ii []int
173}
174
175func NewBar2() *Bar2 {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300176 return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400177}
178
Dmitry Vyukov76477412015-02-19 22:00:11 +0300179func (b *Bar2) NoLeak() int { // ERROR "\(\*Bar2\).NoLeak b does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400180 return b.i[0]
181}
182
David Chase7fbb1b32015-03-26 16:36:15 -0400183func (b *Bar2) Leak() []int { // ERROR "leaking param: b to result ~r0 level=0$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300184 return b.i[:] // ERROR "b.i escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400185}
186
David Chase7fbb1b32015-03-26 16:36:15 -0400187func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param: b to result ~r0 level=1$"
Russ Cox00d2f912014-09-24 15:20:03 -0400188 return b.ii[0:1]
189}
190
Dmitry Vyukov76477412015-02-19 22:00:11 +0300191func (b Bar2) AgainNoLeak() [12]int { // ERROR "Bar2.AgainNoLeak b does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400192 return b.i
193}
194
Dmitry Vyukov76477412015-02-19 22:00:11 +0300195func (b *Bar2) LeakSelf() { // ERROR "leaking param: b$"
196 b.ii = b.i[0:4] // ERROR "b.i escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400197}
198
Dmitry Vyukov76477412015-02-19 22:00:11 +0300199func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b$"
Russ Cox00d2f912014-09-24 15:20:03 -0400200 var buf []int
Dmitry Vyukov76477412015-02-19 22:00:11 +0300201 buf = b.i[0:] // ERROR "b.i escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400202 b.ii = buf
203}
204
205func foo21() func() int {
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300206 x := 42
Dmitry Vyukov76477412015-02-19 22:00:11 +0300207 return func() int { // ERROR "func literal escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300208 return x
209 }
210}
211
212func foo21a() func() int {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300213 x := 42 // ERROR "moved to heap: x$"
214 return func() int { // ERROR "func literal escapes to heap$"
215 x++ // ERROR "&x escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300216 return x
Russ Cox00d2f912014-09-24 15:20:03 -0400217 }
218}
219
220func foo22() int {
221 x := 42
Dmitry Vyukov76477412015-02-19 22:00:11 +0300222 return func() int { // ERROR "foo22 func literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400223 return x
224 }()
225}
226
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300227func foo23(x int) func() int {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300228 return func() int { // ERROR "func literal escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300229 return x
Russ Cox00d2f912014-09-24 15:20:03 -0400230 }
231}
232
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300233func foo23a(x int) func() int {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300234 f := func() int { // ERROR "func literal escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300235 return x
Russ Cox00d2f912014-09-24 15:20:03 -0400236 }
237 return f
238}
239
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300240func foo23b(x int) *(func() int) {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300241 f := func() int { return x } // ERROR "func literal escapes to heap$" "moved to heap: f$"
242 return &f // ERROR "&f escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400243}
244
Dmitry Vyukov76477412015-02-19 22:00:11 +0300245func foo23c(x int) func() int { // ERROR "moved to heap: x$"
246 return func() int { // ERROR "func literal escapes to heap$"
247 x++ // ERROR "&x escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300248 return x
249 }
250}
251
Russ Cox00d2f912014-09-24 15:20:03 -0400252func foo24(x int) int {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300253 return func() int { // ERROR "foo24 func literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400254 return x
255 }()
256}
257
258var x *int
259
Dmitry Vyukov76477412015-02-19 22:00:11 +0300260func fooleak(xx *int) int { // ERROR "leaking param: xx$"
Russ Cox00d2f912014-09-24 15:20:03 -0400261 x = xx
262 return *x
263}
264
Dmitry Vyukov76477412015-02-19 22:00:11 +0300265func foonoleak(xx *int) int { // ERROR "foonoleak xx does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400266 return *x + *xx
267}
268
Dmitry Vyukov76477412015-02-19 22:00:11 +0300269func foo31(x int) int { // ERROR "moved to heap: x$"
270 return fooleak(&x) // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400271}
272
273func foo32(x int) int {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300274 return foonoleak(&x) // ERROR "foo32 &x does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400275}
276
277type Foo struct {
278 xx *int
279 x int
280}
281
282var F Foo
283var pf *Foo
284
Dmitry Vyukov76477412015-02-19 22:00:11 +0300285func (f *Foo) fooleak() { // ERROR "leaking param: f$"
Russ Cox00d2f912014-09-24 15:20:03 -0400286 pf = f
287}
288
Dmitry Vyukov76477412015-02-19 22:00:11 +0300289func (f *Foo) foonoleak() { // ERROR "\(\*Foo\).foonoleak f does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400290 F.x = f.x
291}
292
Dmitry Vyukov76477412015-02-19 22:00:11 +0300293func (f *Foo) Leak() { // ERROR "leaking param: f$"
Russ Cox00d2f912014-09-24 15:20:03 -0400294 f.fooleak()
295}
296
Dmitry Vyukov76477412015-02-19 22:00:11 +0300297func (f *Foo) NoLeak() { // ERROR "\(\*Foo\).NoLeak f does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400298 f.foonoleak()
299}
300
Dmitry Vyukov76477412015-02-19 22:00:11 +0300301func foo41(x int) { // ERROR "moved to heap: x$"
302 F.xx = &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400303}
304
Dmitry Vyukov76477412015-02-19 22:00:11 +0300305func (f *Foo) foo42(x int) { // ERROR "\(\*Foo\).foo42 f does not escape$" "moved to heap: x$"
306 f.xx = &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400307}
308
Dmitry Vyukov76477412015-02-19 22:00:11 +0300309func foo43(f *Foo, x int) { // ERROR "foo43 f does not escape$" "moved to heap: x$"
310 f.xx = &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400311}
312
Dmitry Vyukov76477412015-02-19 22:00:11 +0300313func foo44(yy *int) { // ERROR "leaking param: yy$"
Russ Cox00d2f912014-09-24 15:20:03 -0400314 F.xx = yy
315}
316
Dmitry Vyukov76477412015-02-19 22:00:11 +0300317func (f *Foo) foo45() { // ERROR "\(\*Foo\).foo45 f does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400318 F.x = f.x
319}
320
321// See foo13 above for explanation of why f leaks.
David Chase7fbb1b32015-03-26 16:36:15 -0400322func (f *Foo) foo46() { // ERROR "leaking param content: f$"
Russ Cox00d2f912014-09-24 15:20:03 -0400323 F.xx = f.xx
324}
325
Dmitry Vyukov76477412015-02-19 22:00:11 +0300326func (f *Foo) foo47() { // ERROR "leaking param: f$"
327 f.xx = &f.x // ERROR "&f.x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400328}
329
330var ptrSlice []*int
331
Dmitry Vyukov76477412015-02-19 22:00:11 +0300332func foo50(i *int) { // ERROR "leaking param: i$"
Russ Cox00d2f912014-09-24 15:20:03 -0400333 ptrSlice[0] = i
334}
335
336var ptrMap map[*int]*int
337
Dmitry Vyukov76477412015-02-19 22:00:11 +0300338func foo51(i *int) { // ERROR "leaking param: i$"
Russ Cox00d2f912014-09-24 15:20:03 -0400339 ptrMap[i] = i
340}
341
Dmitry Vyukov76477412015-02-19 22:00:11 +0300342func indaddr1(x int) *int { // ERROR "moved to heap: x$"
343 return &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400344}
345
David Chase7fbb1b32015-03-26 16:36:15 -0400346func indaddr2(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300347 return *&x // ERROR "indaddr2 &x does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400348}
349
David Chase7fbb1b32015-03-26 16:36:15 -0400350func indaddr3(x *int32) *int { // ERROR "leaking param: x to result ~r1 level=0$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300351 return *(**int)(unsafe.Pointer(&x)) // ERROR "indaddr3 &x does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400352}
353
354// From package math:
355
356func Float32bits(f float32) uint32 {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300357 return *(*uint32)(unsafe.Pointer(&f)) // ERROR "Float32bits &f does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400358}
359
360func Float32frombits(b uint32) float32 {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300361 return *(*float32)(unsafe.Pointer(&b)) // ERROR "Float32frombits &b does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400362}
363
364func Float64bits(f float64) uint64 {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300365 return *(*uint64)(unsafe.Pointer(&f)) // ERROR "Float64bits &f does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400366}
367
368func Float64frombits(b uint64) float64 {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300369 return *(*float64)(unsafe.Pointer(&b)) // ERROR "Float64frombits &b does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400370}
371
372// contrast with
Dmitry Vyukov76477412015-02-19 22:00:11 +0300373func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f$"
374 return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400375}
376
David Chase7fbb1b32015-03-26 16:36:15 -0400377func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400378 return (*uint64)(unsafe.Pointer(f))
379}
380
David Chase7fbb1b32015-03-26 16:36:15 -0400381func typesw(i interface{}) *int { // ERROR "leaking param: i to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400382 switch val := i.(type) {
383 case *int:
384 return val
385 case *int8:
Dmitry Vyukov76477412015-02-19 22:00:11 +0300386 v := int(*val) // ERROR "moved to heap: v$"
387 return &v // ERROR "&v escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400388 }
389 return nil
390}
391
David Chase7fbb1b32015-03-26 16:36:15 -0400392func exprsw(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400393 switch j := i; *j + 110 {
394 case 12:
395 return j
396 case 42:
397 return nil
398 }
399 return nil
400
401}
402
403// assigning to an array element is like assigning to the array
David Chase7fbb1b32015-03-26 16:36:15 -0400404func foo60(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400405 var a [12]*int
406 a[0] = i
407 return a[1]
408}
409
Dmitry Vyukov76477412015-02-19 22:00:11 +0300410func foo60a(i *int) *int { // ERROR "foo60a i does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400411 var a [12]*int
412 a[0] = i
413 return nil
414}
415
416// assigning to a struct field is like assigning to the struct
David Chase7fbb1b32015-03-26 16:36:15 -0400417func foo61(i *int) *int { // ERROR "leaking param: i to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400418 type S struct {
419 a, b *int
420 }
421 var s S
422 s.a = i
423 return s.b
424}
425
Dmitry Vyukov76477412015-02-19 22:00:11 +0300426func foo61a(i *int) *int { // ERROR "foo61a i does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400427 type S struct {
428 a, b *int
429 }
430 var s S
431 s.a = i
432 return nil
433}
434
435// assigning to a struct field is like assigning to the struct but
436// here this subtlety is lost, since s.a counts as an assignment to a
437// track-losing dereference.
Dmitry Vyukov76477412015-02-19 22:00:11 +0300438func foo62(i *int) *int { // ERROR "leaking param: i$"
Russ Cox00d2f912014-09-24 15:20:03 -0400439 type S struct {
440 a, b *int
441 }
Dmitry Vyukov76477412015-02-19 22:00:11 +0300442 s := new(S) // ERROR "foo62 new\(S\) does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400443 s.a = i
444 return nil // s.b
445}
446
447type M interface {
448 M()
449}
450
Dmitry Vyukov76477412015-02-19 22:00:11 +0300451func foo63(m M) { // ERROR "foo63 m does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400452}
453
Dmitry Vyukov76477412015-02-19 22:00:11 +0300454func foo64(m M) { // ERROR "leaking param: m$"
Russ Cox00d2f912014-09-24 15:20:03 -0400455 m.M()
456}
457
Dmitry Vyukov76477412015-02-19 22:00:11 +0300458func foo64b(m M) { // ERROR "leaking param: m$"
Russ Cox00d2f912014-09-24 15:20:03 -0400459 defer m.M()
460}
461
462type MV int
463
464func (MV) M() {}
465
466func foo65() {
467 var mv MV
Dmitry Vyukov76477412015-02-19 22:00:11 +0300468 foo63(&mv) // ERROR "foo65 &mv does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400469}
470
471func foo66() {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300472 var mv MV // ERROR "moved to heap: mv$"
473 foo64(&mv) // ERROR "&mv escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400474}
475
476func foo67() {
477 var mv MV
Dmitry Vyukov76477412015-02-19 22:00:11 +0300478 foo63(mv) // ERROR "foo67 mv does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400479}
480
481func foo68() {
482 var mv MV
Dmitry Vyukovedcc0622015-02-19 16:27:32 +0300483 // escapes but it's an int so irrelevant
Dmitry Vyukov76477412015-02-19 22:00:11 +0300484 foo64(mv) // ERROR "mv escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400485}
486
Dmitry Vyukov76477412015-02-19 22:00:11 +0300487func foo69(m M) { // ERROR "leaking param: m$"
Russ Cox00d2f912014-09-24 15:20:03 -0400488 foo64(m)
489}
490
Dmitry Vyukov76477412015-02-19 22:00:11 +0300491func foo70(mv1 *MV, m M) { // ERROR "leaking param: m$" "leaking param: mv1$"
492 m = mv1 // ERROR "mv1 escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400493 foo64(m)
494}
495
Dmitry Vyukov76477412015-02-19 22:00:11 +0300496func foo71(x *int) []*int { // ERROR "leaking param: x$"
Russ Cox00d2f912014-09-24 15:20:03 -0400497 var y []*int
498 y = append(y, x)
499 return y
500}
501
Dmitry Vyukov76477412015-02-19 22:00:11 +0300502func foo71a(x int) []*int { // ERROR "moved to heap: x$"
Russ Cox00d2f912014-09-24 15:20:03 -0400503 var y []*int
Dmitry Vyukov76477412015-02-19 22:00:11 +0300504 y = append(y, &x) // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400505 return y
506}
507
508func foo72() {
509 var x int
510 var y [1]*int
Dmitry Vyukov76477412015-02-19 22:00:11 +0300511 y[0] = &x // ERROR "foo72 &x does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400512}
513
514func foo72aa() [10]*int {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300515 var x int // ERROR "moved to heap: x$"
Russ Cox00d2f912014-09-24 15:20:03 -0400516 var y [10]*int
Dmitry Vyukov76477412015-02-19 22:00:11 +0300517 y[0] = &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400518 return y
519}
520
521func foo72a() {
522 var y [10]*int
523 for i := 0; i < 10; i++ {
524 // escapes its scope
Dmitry Vyukov76477412015-02-19 22:00:11 +0300525 x := i // ERROR "moved to heap: x$"
526 y[i] = &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400527 }
528 return
529}
530
531func foo72b() [10]*int {
532 var y [10]*int
533 for i := 0; i < 10; i++ {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300534 x := i // ERROR "moved to heap: x$"
535 y[i] = &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400536 }
537 return y
538}
539
540// issue 2145
541func foo73() {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300542 s := []int{3, 2, 1} // ERROR "foo73 \[\]int literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400543 for _, v := range s {
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300544 vv := v
545 // actually just escapes its scope
Dmitry Vyukov76477412015-02-19 22:00:11 +0300546 defer func() { // ERROR "func literal escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300547 println(vv)
548 }()
549 }
550}
551
552func foo731() {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300553 s := []int{3, 2, 1} // ERROR "foo731 \[\]int literal does not escape$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300554 for _, v := range s {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300555 vv := v // ERROR "moved to heap: vv$"
Russ Cox00d2f912014-09-24 15:20:03 -0400556 // actually just escapes its scope
Dmitry Vyukov76477412015-02-19 22:00:11 +0300557 defer func() { // ERROR "func literal escapes to heap$"
558 vv = 42 // ERROR "&vv escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300559 println(vv)
Russ Cox00d2f912014-09-24 15:20:03 -0400560 }()
561 }
562}
563
564func foo74() {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300565 s := []int{3, 2, 1} // ERROR "foo74 \[\]int literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400566 for _, v := range s {
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300567 vv := v
568 // actually just escapes its scope
Dmitry Vyukov76477412015-02-19 22:00:11 +0300569 fn := func() { // ERROR "func literal escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300570 println(vv)
571 }
572 defer fn()
573 }
574}
575
576func foo74a() {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300577 s := []int{3, 2, 1} // ERROR "foo74a \[\]int literal does not escape$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300578 for _, v := range s {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300579 vv := v // ERROR "moved to heap: vv$"
Russ Cox00d2f912014-09-24 15:20:03 -0400580 // actually just escapes its scope
Dmitry Vyukov76477412015-02-19 22:00:11 +0300581 fn := func() { // ERROR "func literal escapes to heap$"
582 vv += 1 // ERROR "&vv escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300583 println(vv)
Russ Cox00d2f912014-09-24 15:20:03 -0400584 }
585 defer fn()
586 }
587}
588
589// issue 3975
590func foo74b() {
591 var array [3]func()
Dmitry Vyukov76477412015-02-19 22:00:11 +0300592 s := []int{3, 2, 1} // ERROR "foo74b \[\]int literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400593 for i, v := range s {
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300594 vv := v
595 // actually just escapes its scope
Dmitry Vyukov76477412015-02-19 22:00:11 +0300596 array[i] = func() { // ERROR "func literal escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300597 println(vv)
598 }
599 }
600}
601
602func foo74c() {
603 var array [3]func()
Dmitry Vyukov76477412015-02-19 22:00:11 +0300604 s := []int{3, 2, 1} // ERROR "foo74c \[\]int literal does not escape$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +0300605 for i, v := range s {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300606 vv := v // ERROR "moved to heap: vv$"
Russ Cox00d2f912014-09-24 15:20:03 -0400607 // actually just escapes its scope
Dmitry Vyukov76477412015-02-19 22:00:11 +0300608 array[i] = func() { // ERROR "func literal escapes to heap$"
Russ Coxfd2154f2015-05-27 07:31:56 -0400609 println(&vv) // ERROR "&vv escapes to heap$" "foo74c.func1 &vv does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400610 }
611 }
612}
613
David Chase7fbb1b32015-03-26 16:36:15 -0400614func myprint(y *int, x ...interface{}) *int { // ERROR "leaking param: y to result ~r2 level=0$" "myprint x does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400615 return y
616}
617
David Chase7fbb1b32015-03-26 16:36:15 -0400618func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "leaking param: x to result ~r2 level=0$" "myprint1 y does not escape$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300619 return &x[0] // ERROR "&x\[0\] escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400620}
621
Dmitry Vyukov76477412015-02-19 22:00:11 +0300622func foo75(z *int) { // ERROR "foo75 z does not escape$"
David Chasef7a39a542015-09-30 14:41:00 -0400623 myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75 ... argument does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400624}
625
Dmitry Vyukov76477412015-02-19 22:00:11 +0300626func foo75a(z *int) { // ERROR "foo75a z does not escape$"
David Chasef7a39a542015-09-30 14:41:00 -0400627 myprint1(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75a ... argument does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400628}
629
Dmitry Vyukov76477412015-02-19 22:00:11 +0300630func foo75esc(z *int) { // ERROR "leaking param: z$"
David Chasef7a39a542015-09-30 14:41:00 -0400631 gxx = myprint(z, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo75esc ... argument does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400632}
633
Dmitry Vyukov76477412015-02-19 22:00:11 +0300634func foo75aesc(z *int) { // ERROR "foo75aesc z does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400635 var ppi **interface{} // assignments to pointer dereferences lose track
Dmitry Vyukov76477412015-02-19 22:00:11 +0300636 *ppi = myprint1(z, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400637}
638
Dmitry Vyukov76477412015-02-19 22:00:11 +0300639func foo75aesc1(z *int) { // ERROR "foo75aesc1 z does not escape$"
640 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$"
Dmitry Vyukov1f5617e2015-02-19 17:54:55 +0300641}
642
David Chasef7a39a542015-09-30 14:41:00 -0400643func foo76(z *int) { // ERROR "z does not escape"
644 myprint(nil, z) // ERROR "foo76 ... argument does not escape$" "z does not escape"
Russ Cox00d2f912014-09-24 15:20:03 -0400645}
646
David Chasef7a39a542015-09-30 14:41:00 -0400647func foo76a(z *int) { // ERROR "z does not escape"
648 myprint1(nil, z) // ERROR "foo76a ... argument does not escape$" "z does not escape"
Russ Cox00d2f912014-09-24 15:20:03 -0400649}
650
651func foo76b() {
David Chasef7a39a542015-09-30 14:41:00 -0400652 myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76b ... argument does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400653}
654
655func foo76c() {
David Chasef7a39a542015-09-30 14:41:00 -0400656 myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76c ... argument does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400657}
658
659func foo76d() {
David Chasef7a39a542015-09-30 14:41:00 -0400660 defer myprint(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76d ... argument does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400661}
662
663func foo76e() {
David Chasef7a39a542015-09-30 14:41:00 -0400664 defer myprint1(nil, 1, 2, 3) // ERROR "1 does not escape" "2 does not escape" "3 does not escape" "foo76e ... argument does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400665}
666
667func foo76f() {
668 for {
669 // TODO: This one really only escapes its scope, but we don't distinguish yet.
Dmitry Vyukov76477412015-02-19 22:00:11 +0300670 defer myprint(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400671 }
672}
673
674func foo76g() {
675 for {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300676 defer myprint1(nil, 1, 2, 3) // ERROR "... argument escapes to heap$" "1 escapes to heap$" "2 escapes to heap$" "3 escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400677 }
678}
679
Dmitry Vyukov76477412015-02-19 22:00:11 +0300680func foo77(z []interface{}) { // ERROR "foo77 z does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400681 myprint(nil, z...) // z does not escape
682}
683
Dmitry Vyukov76477412015-02-19 22:00:11 +0300684func foo77a(z []interface{}) { // ERROR "foo77a z does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400685 myprint1(nil, z...)
686}
687
Dmitry Vyukov76477412015-02-19 22:00:11 +0300688func foo77b(z []interface{}) { // ERROR "leaking param: z$"
Russ Cox00d2f912014-09-24 15:20:03 -0400689 var ppi **interface{}
690 *ppi = myprint1(nil, z...)
691}
692
Dmitry Vyukov76477412015-02-19 22:00:11 +0300693func foo77c(z []interface{}) { // ERROR "leaking param: z$"
694 sink = myprint1(nil, z...) // ERROR "myprint1\(nil, z...\) escapes to heap$"
Dmitry Vyukov1f5617e2015-02-19 17:54:55 +0300695}
696
697func dotdotdot() {
David Chasef7a39a542015-09-30 14:41:00 -0400698 i := 0
699 myprint(nil, &i) // ERROR "&i does not escape" "dotdotdot ... argument does not escape$"
Dmitry Vyukov1f5617e2015-02-19 17:54:55 +0300700
David Chasef7a39a542015-09-30 14:41:00 -0400701 j := 0
702 myprint1(nil, &j) // ERROR "&j does not escape" "dotdotdot ... argument does not escape$"
Dmitry Vyukov1f5617e2015-02-19 17:54:55 +0300703}
704
Dmitry Vyukov76477412015-02-19 22:00:11 +0300705func foo78(z int) *int { // ERROR "moved to heap: z$"
706 return &z // ERROR "&z escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400707}
708
Dmitry Vyukov76477412015-02-19 22:00:11 +0300709func foo78a(z int) *int { // ERROR "moved to heap: z$"
710 y := &z // ERROR "&z escapes to heap$"
711 x := &y // ERROR "foo78a &y does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400712 return *x // really return y
713}
714
715func foo79() *int {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300716 return new(int) // ERROR "new\(int\) escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400717}
718
719func foo80() *int {
720 var z *int
721 for {
722 // Really just escapes its scope but we don't distinguish
Dmitry Vyukov76477412015-02-19 22:00:11 +0300723 z = new(int) // ERROR "new\(int\) escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400724 }
725 _ = z
726 return nil
727}
728
729func foo81() *int {
730 for {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300731 z := new(int) // ERROR "foo81 new\(int\) does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400732 _ = z
733 }
734 return nil
735}
736
David Chase7fbb1b32015-03-26 16:36:15 -0400737func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param: p to result x level=0$" "leaking param: p to result y level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400738
Dmitry Vyukov76477412015-02-19 22:00:11 +0300739func noop(x, y *int) {} // ERROR "noop x does not escape$" "noop y does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400740
741func foo82() {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300742 var x, y, z int // ERROR "moved to heap: x$" "moved to heap: y$" "moved to heap: z$"
743 go noop(tee(&z)) // ERROR "&z escapes to heap$"
744 go noop(&x, &y) // ERROR "&x escapes to heap$" "&y escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400745 for {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300746 var u, v, w int // ERROR "moved to heap: u$" "moved to heap: v$" "moved to heap: w$"
747 defer noop(tee(&u)) // ERROR "&u escapes to heap$"
748 defer noop(&v, &w) // ERROR "&v escapes to heap$" "&w escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400749 }
750}
751
752type Fooer interface {
753 Foo()
754}
755
756type LimitedFooer struct {
757 Fooer
758 N int64
759}
760
David Chase7fbb1b32015-03-26 16:36:15 -0400761func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r to result ~r2 level=-1$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300762 return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400763}
764
Dmitry Vyukov76477412015-02-19 22:00:11 +0300765func foo90(x *int) map[*int]*int { // ERROR "leaking param: x$"
766 return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400767}
768
Dmitry Vyukov76477412015-02-19 22:00:11 +0300769func foo91(x *int) map[*int]*int { // ERROR "leaking param: x$"
770 return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400771}
772
David Chase7fbb1b32015-03-26 16:36:15 -0400773func foo92(x *int) [2]*int { // ERROR "leaking param: x to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400774 return [2]*int{x, nil}
775}
776
777// does not leak c
Dmitry Vyukov76477412015-02-19 22:00:11 +0300778func foo93(c chan *int) *int { // ERROR "foo93 c does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400779 for v := range c {
780 return v
781 }
782 return nil
783}
784
785// does not leak m
David Chasea21cf5b2015-05-15 12:19:07 -0400786func foo94(m map[*int]*int, b bool) *int { // ERROR "leaking param: m to result ~r2 level=1"
Russ Cox00d2f912014-09-24 15:20:03 -0400787 for k, v := range m {
788 if b {
789 return k
790 }
791 return v
792 }
793 return nil
794}
795
796// does leak x
Dmitry Vyukov76477412015-02-19 22:00:11 +0300797func foo95(m map[*int]*int, x *int) { // ERROR "foo95 m does not escape$" "leaking param: x$"
Russ Cox00d2f912014-09-24 15:20:03 -0400798 m[x] = x
799}
800
David Chasea21cf5b2015-05-15 12:19:07 -0400801// does not leak m but does leak content
802func foo96(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
Russ Cox00d2f912014-09-24 15:20:03 -0400803 return m[0]
804}
805
806// does leak m
David Chase7fbb1b32015-03-26 16:36:15 -0400807func foo97(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400808 return m[0]
809}
810
811// does not leak m
Dmitry Vyukov76477412015-02-19 22:00:11 +0300812func foo98(m map[int]*int) *int { // ERROR "foo98 m does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400813 return m[0]
814}
815
816// does leak m
David Chase7fbb1b32015-03-26 16:36:15 -0400817func foo99(m *[1]*int) []*int { // ERROR "leaking param: m to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400818 return m[:]
819}
820
821// does not leak m
David Chasea21cf5b2015-05-15 12:19:07 -0400822func foo100(m []*int) *int { // ERROR "leaking param: m to result ~r1 level=1"
Russ Cox00d2f912014-09-24 15:20:03 -0400823 for _, v := range m {
824 return v
825 }
826 return nil
827}
828
829// does leak m
David Chase7fbb1b32015-03-26 16:36:15 -0400830func foo101(m [1]*int) *int { // ERROR "leaking param: m to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400831 for _, v := range m {
832 return v
833 }
834 return nil
835}
836
837// does not leak m
Dmitry Vyukov76477412015-02-19 22:00:11 +0300838func foo101a(m [1]*int) *int { // ERROR "foo101a m does not escape$"
839 for i := range m { // ERROR "moved to heap: i$"
840 return &i // ERROR "&i escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400841 }
842 return nil
843}
844
845// does leak x
Dmitry Vyukov76477412015-02-19 22:00:11 +0300846func foo102(m []*int, x *int) { // ERROR "foo102 m does not escape$" "leaking param: x$"
Russ Cox00d2f912014-09-24 15:20:03 -0400847 m[0] = x
848}
849
850// does not leak x
Dmitry Vyukov76477412015-02-19 22:00:11 +0300851func foo103(m [1]*int, x *int) { // ERROR "foo103 m does not escape$" "foo103 x does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400852 m[0] = x
853}
854
855var y []*int
856
Russ Cox66130902015-06-24 17:31:57 -0400857// does not leak x but does leak content
858func foo104(x []*int) { // ERROR "leaking param content: x"
Russ Cox00d2f912014-09-24 15:20:03 -0400859 copy(y, x)
860}
861
David Chasea21cf5b2015-05-15 12:19:07 -0400862// does not leak x but does leak content
863func foo105(x []*int) { // ERROR "leaking param content: x"
Russ Cox00d2f912014-09-24 15:20:03 -0400864 _ = append(y, x...)
865}
866
867// does leak x
Dmitry Vyukov76477412015-02-19 22:00:11 +0300868func foo106(x *int) { // ERROR "leaking param: x$"
Russ Cox00d2f912014-09-24 15:20:03 -0400869 _ = append(y, x)
870}
871
Dmitry Vyukov76477412015-02-19 22:00:11 +0300872func foo107(x *int) map[*int]*int { // ERROR "leaking param: x$"
873 return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400874}
875
Dmitry Vyukov76477412015-02-19 22:00:11 +0300876func foo108(x *int) map[*int]*int { // ERROR "leaking param: x$"
877 return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400878}
879
Dmitry Vyukov76477412015-02-19 22:00:11 +0300880func foo109(x *int) *int { // ERROR "leaking param: x$"
881 m := map[*int]*int{x: nil} // ERROR "foo109 map\[\*int\]\*int literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400882 for k, _ := range m {
883 return k
884 }
885 return nil
886}
887
Dmitry Vyukov76477412015-02-19 22:00:11 +0300888func foo110(x *int) *int { // ERROR "leaking param: x$"
889 m := map[*int]*int{nil: x} // ERROR "foo110 map\[\*int\]\*int literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400890 return m[nil]
891}
892
David Chasea21cf5b2015-05-15 12:19:07 -0400893func foo111(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300894 m := []*int{x} // ERROR "foo111 \[\]\*int literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400895 return m[0]
896}
897
David Chase7fbb1b32015-03-26 16:36:15 -0400898func foo112(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400899 m := [1]*int{x}
900 return m[0]
901}
902
David Chase7fbb1b32015-03-26 16:36:15 -0400903func foo113(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400904 m := Bar{ii: x}
905 return m.ii
906}
907
David Chase7fbb1b32015-03-26 16:36:15 -0400908func foo114(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
Dmitry Vyukov76477412015-02-19 22:00:11 +0300909 m := &Bar{ii: x} // ERROR "foo114 &Bar literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -0400910 return m.ii
911}
912
David Chase7fbb1b32015-03-26 16:36:15 -0400913func foo115(x *int) *int { // ERROR "leaking param: x to result ~r1 level=0$"
Russ Cox00d2f912014-09-24 15:20:03 -0400914 return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
915}
916
917func foo116(b bool) *int {
918 if b {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300919 x := 1 // ERROR "moved to heap: x$"
920 return &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400921 } else {
Dmitry Vyukov76477412015-02-19 22:00:11 +0300922 y := 1 // ERROR "moved to heap: y$"
923 return &y // ERROR "&y escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400924 }
925 return nil
926}
927
Dmitry Vyukov76477412015-02-19 22:00:11 +0300928func foo117(unknown func(interface{})) { // ERROR "foo117 unknown does not escape$"
929 x := 1 // ERROR "moved to heap: x$"
930 unknown(&x) // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400931}
932
Dmitry Vyukov76477412015-02-19 22:00:11 +0300933func foo118(unknown func(*int)) { // ERROR "foo118 unknown does not escape$"
934 x := 1 // ERROR "moved to heap: x$"
935 unknown(&x) // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -0400936}
937
938func external(*int)
939
Dmitry Vyukov76477412015-02-19 22:00:11 +0300940func foo119(x *int) { // ERROR "leaking param: x$"
Russ Cox00d2f912014-09-24 15:20:03 -0400941 external(x)
942}
943
944func foo120() {
945 // formerly exponential time analysis
946L1:
947L2:
948L3:
949L4:
950L5:
951L6:
952L7:
953L8:
954L9:
955L10:
956L11:
957L12:
958L13:
959L14:
960L15:
961L16:
962L17:
963L18:
964L19:
965L20:
966L21:
967L22:
968L23:
969L24:
970L25:
971L26:
972L27:
973L28:
974L29:
975L30:
976L31:
977L32:
978L33:
979L34:
980L35:
981L36:
982L37:
983L38:
984L39:
985L40:
986L41:
987L42:
988L43:
989L44:
990L45:
991L46:
992L47:
993L48:
994L49:
995L50:
996L51:
997L52:
998L53:
999L54:
1000L55:
1001L56:
1002L57:
1003L58:
1004L59:
1005L60:
1006L61:
1007L62:
1008L63:
1009L64:
1010L65:
1011L66:
1012L67:
1013L68:
1014L69:
1015L70:
1016L71:
1017L72:
1018L73:
1019L74:
1020L75:
1021L76:
1022L77:
1023L78:
1024L79:
1025L80:
1026L81:
1027L82:
1028L83:
1029L84:
1030L85:
1031L86:
1032L87:
1033L88:
1034L89:
1035L90:
1036L91:
1037L92:
1038L93:
1039L94:
1040L95:
1041L96:
1042L97:
1043L98:
1044L99:
1045L100:
1046 // use the labels to silence compiler errors
1047 goto L1
1048 goto L2
1049 goto L3
1050 goto L4
1051 goto L5
1052 goto L6
1053 goto L7
1054 goto L8
1055 goto L9
1056 goto L10
1057 goto L11
1058 goto L12
1059 goto L13
1060 goto L14
1061 goto L15
1062 goto L16
1063 goto L17
1064 goto L18
1065 goto L19
1066 goto L20
1067 goto L21
1068 goto L22
1069 goto L23
1070 goto L24
1071 goto L25
1072 goto L26
1073 goto L27
1074 goto L28
1075 goto L29
1076 goto L30
1077 goto L31
1078 goto L32
1079 goto L33
1080 goto L34
1081 goto L35
1082 goto L36
1083 goto L37
1084 goto L38
1085 goto L39
1086 goto L40
1087 goto L41
1088 goto L42
1089 goto L43
1090 goto L44
1091 goto L45
1092 goto L46
1093 goto L47
1094 goto L48
1095 goto L49
1096 goto L50
1097 goto L51
1098 goto L52
1099 goto L53
1100 goto L54
1101 goto L55
1102 goto L56
1103 goto L57
1104 goto L58
1105 goto L59
1106 goto L60
1107 goto L61
1108 goto L62
1109 goto L63
1110 goto L64
1111 goto L65
1112 goto L66
1113 goto L67
1114 goto L68
1115 goto L69
1116 goto L70
1117 goto L71
1118 goto L72
1119 goto L73
1120 goto L74
1121 goto L75
1122 goto L76
1123 goto L77
1124 goto L78
1125 goto L79
1126 goto L80
1127 goto L81
1128 goto L82
1129 goto L83
1130 goto L84
1131 goto L85
1132 goto L86
1133 goto L87
1134 goto L88
1135 goto L89
1136 goto L90
1137 goto L91
1138 goto L92
1139 goto L93
1140 goto L94
1141 goto L95
1142 goto L96
1143 goto L97
1144 goto L98
1145 goto L99
1146 goto L100
1147}
1148
1149func foo121() {
1150 for i := 0; i < 10; i++ {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001151 defer myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
1152 go myprint(nil, i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001153 }
1154}
1155
1156// same as foo121 but check across import
1157func foo121b() {
1158 for i := 0; i < 10; i++ {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001159 defer fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
1160 go fmt.Printf("%d", i) // ERROR "... argument escapes to heap$" "i escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001161 }
1162}
1163
1164// a harmless forward jump
1165func foo122() {
1166 var i *int
1167
1168 goto L1
1169L1:
Dmitry Vyukov76477412015-02-19 22:00:11 +03001170 i = new(int) // ERROR "foo122 new\(int\) does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001171 _ = i
1172}
1173
1174// a backward jump, increases loopdepth
1175func foo123() {
1176 var i *int
1177
1178L1:
Dmitry Vyukov76477412015-02-19 22:00:11 +03001179 i = new(int) // ERROR "new\(int\) escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001180
1181 goto L1
1182 _ = i
1183}
1184
Dmitry Vyukov76477412015-02-19 22:00:11 +03001185func foo124(x **int) { // ERROR "foo124 x does not escape$"
1186 var i int // ERROR "moved to heap: i$"
1187 p := &i // ERROR "&i escapes to heap$"
1188 func() { // ERROR "foo124 func literal does not escape$"
1189 *x = p // ERROR "leaking closure reference p$"
Russ Cox00d2f912014-09-24 15:20:03 -04001190 }()
1191}
1192
Dmitry Vyukov76477412015-02-19 22:00:11 +03001193func foo125(ch chan *int) { // ERROR "foo125 ch does not escape$"
1194 var i int // ERROR "moved to heap: i$"
1195 p := &i // ERROR "&i escapes to heap$"
1196 func() { // ERROR "foo125 func literal does not escape$"
1197 ch <- p // ERROR "leaking closure reference p$"
Russ Cox00d2f912014-09-24 15:20:03 -04001198 }()
1199}
1200
1201func foo126() {
1202 var px *int // loopdepth 0
1203 for {
1204 // loopdepth 1
Dmitry Vyukov76477412015-02-19 22:00:11 +03001205 var i int // ERROR "moved to heap: i$"
1206 func() { // ERROR "foo126 func literal does not escape$"
David Chasee779bfa2016-01-04 16:44:20 -05001207 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i"
Russ Cox00d2f912014-09-24 15:20:03 -04001208 }()
1209 }
1210 _ = px
1211}
1212
1213var px *int
1214
1215func foo127() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001216 var i int // ERROR "moved to heap: i$"
1217 p := &i // ERROR "&i escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001218 q := p
1219 px = q
1220}
1221
1222func foo128() {
1223 var i int
Dmitry Vyukov76477412015-02-19 22:00:11 +03001224 p := &i // ERROR "foo128 &i does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001225 q := p
1226 _ = q
1227}
1228
1229func foo129() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001230 var i int // ERROR "moved to heap: i$"
1231 p := &i // ERROR "&i escapes to heap$"
1232 func() { // ERROR "foo129 func literal does not escape$"
1233 q := p // ERROR "leaking closure reference p$"
Russ Coxfd2154f2015-05-27 07:31:56 -04001234 func() { // ERROR "foo129.func1 func literal does not escape$"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001235 r := q // ERROR "leaking closure reference q$"
Russ Cox00d2f912014-09-24 15:20:03 -04001236 px = r
1237 }()
1238 }()
1239}
1240
1241func foo130() {
1242 for {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001243 var i int // ERROR "moved to heap: i$"
1244 func() { // ERROR "foo130 func literal does not escape$"
1245 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$"
Russ Cox00d2f912014-09-24 15:20:03 -04001246 }()
1247 }
1248}
1249
1250func foo131() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001251 var i int // ERROR "moved to heap: i$"
1252 func() { // ERROR "foo131 func literal does not escape$"
1253 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$"
Russ Cox00d2f912014-09-24 15:20:03 -04001254 }()
1255}
1256
1257func foo132() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001258 var i int // ERROR "moved to heap: i$"
1259 go func() { // ERROR "func literal escapes to heap$"
1260 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$"
Russ Cox00d2f912014-09-24 15:20:03 -04001261 }()
1262}
1263
1264func foo133() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001265 var i int // ERROR "moved to heap: i$"
1266 defer func() { // ERROR "foo133 func literal does not escape$"
1267 px = &i // ERROR "&i escapes to heap$" "leaking closure reference i$"
Russ Cox00d2f912014-09-24 15:20:03 -04001268 }()
1269}
1270
1271func foo134() {
1272 var i int
Dmitry Vyukov76477412015-02-19 22:00:11 +03001273 p := &i // ERROR "foo134 &i does not escape$"
1274 func() { // ERROR "foo134 func literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001275 q := p
Russ Coxfd2154f2015-05-27 07:31:56 -04001276 func() { // ERROR "foo134.func1 func literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001277 r := q
1278 _ = r
1279 }()
1280 }()
1281}
1282
1283func foo135() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001284 var i int // ERROR "moved to heap: i$"
1285 p := &i // ERROR "&i escapes to heap$"
1286 go func() { // ERROR "func literal escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03001287 q := p
Russ Coxfd2154f2015-05-27 07:31:56 -04001288 func() { // ERROR "foo135.func1 func literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001289 r := q
1290 _ = r
1291 }()
1292 }()
1293}
1294
1295func foo136() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001296 var i int // ERROR "moved to heap: i$"
1297 p := &i // ERROR "&i escapes to heap$"
1298 go func() { // ERROR "func literal escapes to heap$"
1299 q := p // ERROR "leaking closure reference p$"
Russ Coxfd2154f2015-05-27 07:31:56 -04001300 func() { // ERROR "foo136.func1 func literal does not escape$"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001301 r := q // ERROR "leaking closure reference q$"
Russ Cox00d2f912014-09-24 15:20:03 -04001302 px = r
1303 }()
1304 }()
1305}
1306
1307func foo137() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001308 var i int // ERROR "moved to heap: i$"
1309 p := &i // ERROR "&i escapes to heap$"
1310 func() { // ERROR "foo137 func literal does not escape$"
1311 q := p // ERROR "leaking closure reference p$"
1312 go func() { // ERROR "func literal escapes to heap$"
Dmitry Vyukov0e80b2e2015-01-19 22:59:58 +03001313 r := q
Russ Cox00d2f912014-09-24 15:20:03 -04001314 _ = r
1315 }()
1316 }()
1317}
1318
1319func foo138() *byte {
1320 type T struct {
1321 x [1]byte
1322 }
Dmitry Vyukov76477412015-02-19 22:00:11 +03001323 t := new(T) // ERROR "new\(T\) escapes to heap$"
1324 return &t.x[0] // ERROR "&t.x\[0\] escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001325}
1326
1327func foo139() *byte {
1328 type T struct {
1329 x struct {
1330 y byte
1331 }
1332 }
Dmitry Vyukov76477412015-02-19 22:00:11 +03001333 t := new(T) // ERROR "new\(T\) escapes to heap$"
1334 return &t.x.y // ERROR "&t.x.y escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001335}
1336
1337// issue 4751
1338func foo140() interface{} {
1339 type T struct {
1340 X string
1341 }
1342 type U struct {
1343 X string
1344 T *T
1345 }
Dmitry Vyukov76477412015-02-19 22:00:11 +03001346 t := &T{} // ERROR "&T literal escapes to heap$"
1347 return U{ // ERROR "U literal escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001348 X: t.X,
1349 T: t,
1350 }
1351}
1352
1353//go:noescape
1354
1355func F1([]byte)
1356
1357func F2([]byte)
1358
1359//go:noescape
1360
Dmitry Vyukov76477412015-02-19 22:00:11 +03001361func F3(x []byte) // ERROR "F3 x does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001362
1363func F4(x []byte)
1364
1365func G() {
1366 var buf1 [10]byte
Dmitry Vyukov76477412015-02-19 22:00:11 +03001367 F1(buf1[:]) // ERROR "G buf1 does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001368
Dmitry Vyukov76477412015-02-19 22:00:11 +03001369 var buf2 [10]byte // ERROR "moved to heap: buf2$"
1370 F2(buf2[:]) // ERROR "buf2 escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001371
1372 var buf3 [10]byte
Dmitry Vyukov76477412015-02-19 22:00:11 +03001373 F3(buf3[:]) // ERROR "G buf3 does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001374
Dmitry Vyukov76477412015-02-19 22:00:11 +03001375 var buf4 [10]byte // ERROR "moved to heap: buf4$"
1376 F4(buf4[:]) // ERROR "buf4 escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001377}
1378
1379type Tm struct {
1380 x int
1381}
1382
Dmitry Vyukov76477412015-02-19 22:00:11 +03001383func (t *Tm) M() { // ERROR "\(\*Tm\).M t does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001384}
1385
1386func foo141() {
1387 var f func()
1388
Dmitry Vyukov76477412015-02-19 22:00:11 +03001389 t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
1390 f = t.M // ERROR "foo141 t.M does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001391 _ = f
1392}
1393
1394var gf func()
1395
1396func foo142() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001397 t := new(Tm) // ERROR "new\(Tm\) escapes to heap$"
1398 gf = t.M // ERROR "t.M escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001399}
1400
1401// issue 3888.
1402func foo143() {
1403 for i := 0; i < 1000; i++ {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001404 func() { // ERROR "foo143 func literal does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001405 for i := 0; i < 1; i++ {
1406 var t Tm
Russ Coxfd2154f2015-05-27 07:31:56 -04001407 t.M() // ERROR "foo143.func1 t does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001408 }
1409 }()
1410 }
1411}
1412
1413// issue 5773
1414// Check that annotations take effect regardless of whether they
1415// are before or after the use in the source code.
1416
1417//go:noescape
1418
1419func foo144a(*int)
1420
1421func foo144() {
1422 var x int
Dmitry Vyukov76477412015-02-19 22:00:11 +03001423 foo144a(&x) // ERROR "foo144 &x does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001424 var y int
Dmitry Vyukov76477412015-02-19 22:00:11 +03001425 foo144b(&y) // ERROR "foo144 &y does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001426}
1427
1428//go:noescape
1429
1430func foo144b(*int)
1431
1432// issue 7313: for loop init should not be treated as "in loop"
1433
1434type List struct {
1435 Next *List
1436}
1437
Dmitry Vyukov76477412015-02-19 22:00:11 +03001438func foo145(l List) { // ERROR "foo145 l does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001439 var p *List
Dmitry Vyukov76477412015-02-19 22:00:11 +03001440 for p = &l; p.Next != nil; p = p.Next { // ERROR "foo145 &l does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001441 }
1442}
1443
Dmitry Vyukov76477412015-02-19 22:00:11 +03001444func foo146(l List) { // ERROR "foo146 l does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001445 var p *List
Dmitry Vyukov76477412015-02-19 22:00:11 +03001446 p = &l // ERROR "foo146 &l does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001447 for ; p.Next != nil; p = p.Next {
1448 }
1449}
1450
Dmitry Vyukov76477412015-02-19 22:00:11 +03001451func foo147(l List) { // ERROR "foo147 l does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001452 var p *List
Dmitry Vyukov76477412015-02-19 22:00:11 +03001453 p = &l // ERROR "foo147 &l does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001454 for p.Next != nil {
1455 p = p.Next
1456 }
1457}
1458
Dmitry Vyukov76477412015-02-19 22:00:11 +03001459func foo148(l List) { // ERROR "foo148 l does not escape$"
1460 for p := &l; p.Next != nil; p = p.Next { // ERROR "foo148 &l does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001461 }
1462}
1463
1464// related: address of variable should have depth of variable, not of loop
1465
Dmitry Vyukov76477412015-02-19 22:00:11 +03001466func foo149(l List) { // ERROR "foo149 l does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001467 var p *List
1468 for {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001469 for p = &l; p.Next != nil; p = p.Next { // ERROR "foo149 &l does not escape$"
Russ Cox00d2f912014-09-24 15:20:03 -04001470 }
1471 }
1472}
1473
1474// issue 7934: missed ... if element type had no pointers
1475
1476var save150 []byte
1477
Dmitry Vyukov76477412015-02-19 22:00:11 +03001478func foo150(x ...byte) { // ERROR "leaking param: x$"
Russ Cox00d2f912014-09-24 15:20:03 -04001479 save150 = x
1480}
1481
1482func bar150() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001483 foo150(1, 2, 3) // ERROR "... argument escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001484}
1485
1486// issue 7931: bad handling of slice of array
1487
1488var save151 *int
1489
Dmitry Vyukov76477412015-02-19 22:00:11 +03001490func foo151(x *int) { // ERROR "leaking param: x$"
Russ Cox00d2f912014-09-24 15:20:03 -04001491 save151 = x
1492}
1493
1494func bar151() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001495 var a [64]int // ERROR "moved to heap: a$"
Russ Cox00d2f912014-09-24 15:20:03 -04001496 a[4] = 101
Dmitry Vyukov76477412015-02-19 22:00:11 +03001497 foo151(&(&a)[4:8][0]) // ERROR "&\(&a\)\[4:8\]\[0\] escapes to heap$" "&a escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001498}
1499
1500func bar151b() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001501 var a [10]int // ERROR "moved to heap: a$"
1502 b := a[:] // ERROR "a escapes to heap$"
1503 foo151(&b[4:8][0]) // ERROR "&b\[4:8\]\[0\] escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001504}
1505
1506func bar151c() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001507 var a [64]int // ERROR "moved to heap: a$"
Russ Cox00d2f912014-09-24 15:20:03 -04001508 a[4] = 101
Dmitry Vyukov76477412015-02-19 22:00:11 +03001509 foo151(&(&a)[4:8:8][0]) // ERROR "&\(&a\)\[4:8:8\]\[0\] escapes to heap$" "&a escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001510}
1511
1512func bar151d() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001513 var a [10]int // ERROR "moved to heap: a$"
1514 b := a[:] // ERROR "a escapes to heap$"
1515 foo151(&b[4:8:8][0]) // ERROR "&b\[4:8:8\]\[0\] escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001516}
1517
1518// issue 8120
1519
1520type U struct {
1521 s *string
1522}
1523
David Chase7fbb1b32015-03-26 16:36:15 -04001524func (u *U) String() *string { // ERROR "leaking param: u to result ~r0 level=1$"
Russ Cox00d2f912014-09-24 15:20:03 -04001525 return u.s
1526}
1527
1528type V struct {
1529 s *string
1530}
1531
David Chase7fbb1b32015-03-26 16:36:15 -04001532// BAD -- level of leak ought to be 0
1533func NewV(u U) *V { // ERROR "leaking param: u to result ~r1 level=-1"
1534 return &V{u.String()} // ERROR "&V literal escapes to heap$" "NewV u does not escape"
Russ Cox00d2f912014-09-24 15:20:03 -04001535}
1536
1537func foo152() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001538 a := "a" // ERROR "moved to heap: a$"
1539 u := U{&a} // ERROR "&a escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001540 v := NewV(u)
1541 println(v)
1542}
1543
1544// issue 8176 - &x in type switch body not marked as escaping
1545
David Chase7fbb1b32015-03-26 16:36:15 -04001546func foo153(v interface{}) *int { // ERROR "leaking param: v to result ~r1 level=-1$"
Russ Cox00d2f912014-09-24 15:20:03 -04001547 switch x := v.(type) {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001548 case int: // ERROR "moved to heap: x$"
1549 return &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001550 }
1551 panic(0)
1552}
1553
1554// issue 8185 - &result escaping into result
1555
Dmitry Vyukov76477412015-02-19 22:00:11 +03001556func f() (x int, y *int) { // ERROR "moved to heap: x$"
1557 y = &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001558 return
1559}
1560
Dmitry Vyukov76477412015-02-19 22:00:11 +03001561func g() (x interface{}) { // ERROR "moved to heap: x$"
1562 x = &x // ERROR "&x escapes to heap$"
Russ Cox00d2f912014-09-24 15:20:03 -04001563 return
1564}
Dmitry Vyukov1b87f012015-01-19 23:46:22 +03001565
1566var sink interface{}
1567
1568type Lit struct {
1569 p *int
1570}
1571
1572func ptrlitNoescape() {
1573 // Both literal and element do not escape.
1574 i := 0
Dmitry Vyukov76477412015-02-19 22:00:11 +03001575 x := &Lit{&i} // ERROR "ptrlitNoescape &Lit literal does not escape$" "ptrlitNoescape &i does not escape$"
Dmitry Vyukov1b87f012015-01-19 23:46:22 +03001576 _ = x
1577}
1578
1579func ptrlitNoEscape2() {
1580 // Literal does not escape, but element does.
Dmitry Vyukov76477412015-02-19 22:00:11 +03001581 i := 0 // ERROR "moved to heap: i$"
1582 x := &Lit{&i} // ERROR "&i escapes to heap$" "ptrlitNoEscape2 &Lit literal does not escape$"
1583 sink = *x // ERROR "\*x escapes to heap$"
Dmitry Vyukov1b87f012015-01-19 23:46:22 +03001584}
1585
1586func ptrlitEscape() {
1587 // Both literal and element escape.
Dmitry Vyukov76477412015-02-19 22:00:11 +03001588 i := 0 // ERROR "moved to heap: i$"
1589 x := &Lit{&i} // ERROR "&Lit literal escapes to heap$" "&i escapes to heap$"
1590 sink = x // ERROR "x escapes to heap$"
Dmitry Vyukov1b87f012015-01-19 23:46:22 +03001591}
Dmitry Vyukov22c16b42015-01-16 23:30:35 +03001592
1593// self-assignments
1594
1595type Buffer struct {
1596 arr [64]byte
1597 buf1 []byte
1598 buf2 []byte
1599 str1 string
1600 str2 string
1601}
1602
Dmitry Vyukov76477412015-02-19 22:00:11 +03001603func (b *Buffer) foo() { // ERROR "\(\*Buffer\).foo b does not escape$"
1604 b.buf1 = b.buf1[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
1605 b.buf1 = b.buf1[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
1606 b.buf1 = b.buf2[1:2] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
1607 b.buf1 = b.buf2[1:2:3] // ERROR "\(\*Buffer\).foo ignoring self-assignment to b.buf1$"
Dmitry Vyukov22c16b42015-01-16 23:30:35 +03001608}
1609
Dmitry Vyukov76477412015-02-19 22:00:11 +03001610func (b *Buffer) bar() { // ERROR "leaking param: b$"
1611 b.buf1 = b.arr[1:2] // ERROR "b.arr escapes to heap$"
Dmitry Vyukov22c16b42015-01-16 23:30:35 +03001612}
1613
Dmitry Vyukov76477412015-02-19 22:00:11 +03001614func (b *Buffer) baz() { // ERROR "\(\*Buffer\).baz b does not escape$"
1615 b.str1 = b.str1[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$"
1616 b.str1 = b.str2[1:2] // ERROR "\(\*Buffer\).baz ignoring self-assignment to b.str1$"
Dmitry Vyukov22c16b42015-01-16 23:30:35 +03001617}
1618
David Chase7fbb1b32015-03-26 16:36:15 -04001619func (b *Buffer) bat() { // ERROR "leaking param content: b$"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001620 o := new(Buffer) // ERROR "new\(Buffer\) escapes to heap$"
Dmitry Vyukov22c16b42015-01-16 23:30:35 +03001621 o.buf1 = b.buf1[1:2]
Dmitry Vyukov76477412015-02-19 22:00:11 +03001622 sink = o // ERROR "o escapes to heap$"
Dmitry Vyukov22c16b42015-01-16 23:30:35 +03001623}
1624
Dmitry Vyukov76477412015-02-19 22:00:11 +03001625func quux(sp *string, bp *[]byte) { // ERROR "quux bp does not escape$" "quux sp does not escape$"
1626 *sp = (*sp)[1:2] // ERROR "quux ignoring self-assignment to \*sp$"
1627 *bp = (*bp)[1:2] // ERROR "quux ignoring self-assignment to \*bp$"
Dmitry Vyukov22c16b42015-01-16 23:30:35 +03001628}
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001629
1630type StructWithString struct {
1631 p *int
1632 s string
1633}
1634
1635// This is escape analysis false negative.
1636// We assign the pointer to x.p but leak x.s. Escape analysis coarsens flows
1637// to just x, and thus &i looks escaping.
1638func fieldFlowTracking() {
1639 var x StructWithString
Dmitry Vyukov76477412015-02-19 22:00:11 +03001640 i := 0 // ERROR "moved to heap: i$"
1641 x.p = &i // ERROR "&i escapes to heap$"
1642 sink = x.s // ERROR "x.s escapes to heap$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001643}
1644
1645// String operations.
1646
1647func slicebytetostring0() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001648 b := make([]byte, 20) // ERROR "slicebytetostring0 make\(\[\]byte, 20\) does not escape$"
1649 s := string(b) // ERROR "slicebytetostring0 string\(b\) does not escape$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001650 _ = s
1651}
1652
1653func slicebytetostring1() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001654 b := make([]byte, 20) // ERROR "slicebytetostring1 make\(\[\]byte, 20\) does not escape$"
1655 s := string(b) // ERROR "slicebytetostring1 string\(b\) does not escape$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001656 s1 := s[0:1]
1657 _ = s1
1658}
1659
1660func slicebytetostring2() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001661 b := make([]byte, 20) // ERROR "slicebytetostring2 make\(\[\]byte, 20\) does not escape$"
1662 s := string(b) // ERROR "string\(b\) escapes to heap$"
1663 s1 := s[0:1] // ERROR "moved to heap: s1$"
1664 sink = &s1 // ERROR "&s1 escapes to heap$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001665}
1666
1667func slicebytetostring3() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001668 b := make([]byte, 20) // ERROR "slicebytetostring3 make\(\[\]byte, 20\) does not escape$"
1669 s := string(b) // ERROR "string\(b\) escapes to heap$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001670 s1 := s[0:1]
Dmitry Vyukov76477412015-02-19 22:00:11 +03001671 sink = s1 // ERROR "s1 escapes to heap$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001672}
1673
1674func addstr0() {
1675 s0 := "a"
1676 s1 := "b"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001677 s := s0 + s1 // ERROR "addstr0 s0 \+ s1 does not escape$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001678 _ = s
1679}
1680
1681func addstr1() {
1682 s0 := "a"
1683 s1 := "b"
1684 s := "c"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001685 s += s0 + s1 // ERROR "addstr1 s0 \+ s1 does not escape$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001686 _ = s
1687}
1688
1689func addstr2() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001690 b := make([]byte, 20) // ERROR "addstr2 make\(\[\]byte, 20\) does not escape$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001691 s0 := "a"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001692 s := string(b) + s0 // ERROR "addstr2 string\(b\) \+ s0 does not escape$" "addstr2 string\(b\) does not escape$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001693 _ = s
1694}
1695
1696func addstr3() {
1697 s0 := "a"
1698 s1 := "b"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001699 s := s0 + s1 // ERROR "s0 \+ s1 escapes to heap$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001700 s2 := s[0:1]
Dmitry Vyukov76477412015-02-19 22:00:11 +03001701 sink = s2 // ERROR "s2 escapes to heap$"
Dmitry Vyukove6fac082015-01-21 17:37:59 +03001702}
Dmitry Vyukov4ce4d8b2015-01-28 08:42:20 +03001703
1704func intstring0() bool {
1705 // string does not escape
1706 x := '0'
Dmitry Vyukov76477412015-02-19 22:00:11 +03001707 s := string(x) // ERROR "intstring0 string\(x\) does not escape$"
Dmitry Vyukov4ce4d8b2015-01-28 08:42:20 +03001708 return s == "0"
1709}
1710
1711func intstring1() string {
1712 // string does not escape, but the buffer does
1713 x := '0'
Dmitry Vyukov76477412015-02-19 22:00:11 +03001714 s := string(x) // ERROR "string\(x\) escapes to heap$"
Dmitry Vyukov4ce4d8b2015-01-28 08:42:20 +03001715 return s
1716}
1717
1718func intstring2() {
1719 // string escapes to heap
1720 x := '0'
Dmitry Vyukov76477412015-02-19 22:00:11 +03001721 s := string(x) // ERROR "moved to heap: s$" "string\(x\) escapes to heap$"
1722 sink = &s // ERROR "&s escapes to heap$"
Dmitry Vyukov4ce4d8b2015-01-28 08:42:20 +03001723}
Dmitry Vyukov95681262015-01-30 09:14:13 +03001724
1725func stringtoslicebyte0() {
1726 s := "foo"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001727 x := []byte(s) // ERROR "stringtoslicebyte0 \(\[\]byte\)\(s\) does not escape$"
Dmitry Vyukov95681262015-01-30 09:14:13 +03001728 _ = x
1729}
1730
1731func stringtoslicebyte1() []byte {
1732 s := "foo"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001733 return []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
Dmitry Vyukov95681262015-01-30 09:14:13 +03001734}
1735
1736func stringtoslicebyte2() {
1737 s := "foo"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001738 sink = []byte(s) // ERROR "\(\[\]byte\)\(s\) escapes to heap$"
Dmitry Vyukov95681262015-01-30 09:14:13 +03001739}
1740
1741func stringtoslicerune0() {
1742 s := "foo"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001743 x := []rune(s) // ERROR "stringtoslicerune0 \(\[\]rune\)\(s\) does not escape$"
Dmitry Vyukov95681262015-01-30 09:14:13 +03001744 _ = x
1745}
1746
1747func stringtoslicerune1() []rune {
1748 s := "foo"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001749 return []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
Dmitry Vyukov95681262015-01-30 09:14:13 +03001750}
1751
1752func stringtoslicerune2() {
1753 s := "foo"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001754 sink = []rune(s) // ERROR "\(\[\]rune\)\(s\) escapes to heap$"
Dmitry Vyukov95681262015-01-30 09:14:13 +03001755}
1756
1757func slicerunetostring0() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001758 r := []rune{1, 2, 3} // ERROR "slicerunetostring0 \[\]rune literal does not escape$"
1759 s := string(r) // ERROR "slicerunetostring0 string\(r\) does not escape$"
Dmitry Vyukov95681262015-01-30 09:14:13 +03001760 _ = s
1761}
1762
1763func slicerunetostring1() string {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001764 r := []rune{1, 2, 3} // ERROR "slicerunetostring1 \[\]rune literal does not escape$"
1765 return string(r) // ERROR "string\(r\) escapes to heap$"
Dmitry Vyukov95681262015-01-30 09:14:13 +03001766}
1767
1768func slicerunetostring2() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001769 r := []rune{1, 2, 3} // ERROR "slicerunetostring2 \[\]rune literal does not escape$"
1770 sink = string(r) // ERROR "string\(r\) escapes to heap$"
Dmitry Vyukov95681262015-01-30 09:14:13 +03001771}
Dmitry Vyukovb3be3602015-01-29 19:40:02 +03001772
1773func makemap0() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001774 m := make(map[int]int) // ERROR "makemap0 make\(map\[int\]int\) does not escape$"
Dmitry Vyukovb3be3602015-01-29 19:40:02 +03001775 m[0] = 0
1776 m[1]++
1777 delete(m, 1)
Dmitry Vyukov76477412015-02-19 22:00:11 +03001778 sink = m[0] // ERROR "m\[0\] escapes to heap$"
Dmitry Vyukovb3be3602015-01-29 19:40:02 +03001779}
1780
1781func makemap1() map[int]int {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001782 return make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
Dmitry Vyukovb3be3602015-01-29 19:40:02 +03001783}
1784
1785func makemap2() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001786 m := make(map[int]int) // ERROR "make\(map\[int\]int\) escapes to heap$"
1787 sink = m // ERROR "m escapes to heap$"
Dmitry Vyukovedcc0622015-02-19 16:27:32 +03001788}
1789
Dmitry Vyukov76477412015-02-19 22:00:11 +03001790func nonescapingEface(m map[interface{}]bool) bool { // ERROR "nonescapingEface m does not escape$"
1791 return m["foo"] // ERROR "nonescapingEface .foo. does not escape$"
Dmitry Vyukovedcc0622015-02-19 16:27:32 +03001792}
1793
Dmitry Vyukov76477412015-02-19 22:00:11 +03001794func nonescapingIface(m map[M]bool) bool { // ERROR "nonescapingIface m does not escape$"
1795 return m[MV(0)] // ERROR "nonescapingIface MV\(0\) does not escape$"
Dmitry Vyukovb3be3602015-01-29 19:40:02 +03001796}
Dmitry Vyukov878a86a2015-04-06 18:17:20 +03001797
1798func issue10353() {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001799 x := new(int) // ERROR "new\(int\) escapes to heap$"
Dmitry Vyukov878a86a2015-04-06 18:17:20 +03001800 issue10353a(x)()
1801}
1802
David Chase7fbb1b32015-03-26 16:36:15 -04001803func issue10353a(x *int) func() { // ERROR "leaking param: x to result ~r1 level=-1$"
Dmitry Vyukov76477412015-02-19 22:00:11 +03001804 return func() { // ERROR "func literal escapes to heap$"
Dmitry Vyukov878a86a2015-04-06 18:17:20 +03001805 println(*x)
1806 }
1807}
1808
1809func issue10353b() {
1810 var f func()
1811 for {
Dmitry Vyukov76477412015-02-19 22:00:11 +03001812 x := new(int) // ERROR "new\(int\) escapes to heap$"
1813 f = func() { // ERROR "func literal escapes to heap$"
Dmitry Vyukov878a86a2015-04-06 18:17:20 +03001814 println(*x)
1815 }
1816 }
1817 _ = f
1818}
Russ Cox66130902015-06-24 17:31:57 -04001819
1820func issue11387(x int) func() int {
1821 f := func() int { return x } // ERROR "func literal escapes to heap"
1822 slice1 := []func() int{f} // ERROR "\[\].* does not escape"
1823 slice2 := make([]func() int, 1) // ERROR "make\(.*\) does not escape"
1824 copy(slice2, slice1)
1825 return slice2[0]
1826}
Tobias Klauserd7ec89c2017-08-10 12:58:10 +02001827
1828func issue12397(x, y int) { // ERROR "moved to heap: y$"
1829 // x does not escape below, because all relevant code is dead.
1830 if false {
1831 gxx = &x
1832 } else {
1833 gxx = &y // ERROR "&y escapes to heap$"
1834 }
1835
1836 if true {
1837 gxx = &y // ERROR "&y escapes to heap$"
1838 } else {
1839 gxx = &x
1840 }
1841}