blob: 6a46ce86abd4173cc549967658f1107cbb278c31 [file] [log] [blame]
Russ Coxcd22afa2012-09-23 13:16:14 -04001// errorcheck -0 -m -l
Luuk van Dijk847b61b2011-08-24 19:07:08 +02002
3// Copyright 2010 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.
6
Rob Pike83976e32012-02-19 14:28:53 +11007// Test, using compiler diagnostic flags, that the escape analysis is working.
Russ Cox075eef42012-02-23 23:09:53 -05008// Compiles but does not run. Inlining is disabled.
Rob Pike83976e32012-02-19 14:28:53 +11009
Russ Cox00d2f912014-09-24 15:20:03 -040010// escape2n.go contains all the same tests but compiles with -N.
11
Luuk van Dijk847b61b2011-08-24 19:07:08 +020012package foo
13
Russ Coxb4df33a2011-11-01 11:02:43 -040014import (
15 "fmt"
16 "unsafe"
17)
Luuk van Dijk847b61b2011-08-24 19:07:08 +020018
19var gxx *int
20
Luuk van Dijkb536adb2011-10-08 19:37:06 +020021func foo1(x int) { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -040022 gxx = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020023}
24
Luuk van Dijkb536adb2011-10-08 19:37:06 +020025func foo2(yy *int) { // ERROR "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020026 gxx = yy
27}
28
Luuk van Dijkb536adb2011-10-08 19:37:06 +020029func foo3(x int) *int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -040030 return &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020031}
32
33type T *T
Russ Coxdb5f9da2011-08-28 12:05:00 -040034
Luuk van Dijkb536adb2011-10-08 19:37:06 +020035func foo3b(t T) { // ERROR "leaking param: t"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020036 *t = t
37}
38
39// xx isn't going anywhere, so use of yy is ok
Russ Coxdb5f9da2011-08-28 12:05:00 -040040func foo4(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020041 xx = yy
42}
43
44// xx isn't going anywhere, so taking address of yy is ok
Russ Coxdb5f9da2011-08-28 12:05:00 -040045func foo5(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
Russ Coxb4df33a2011-11-01 11:02:43 -040046 xx = &yy // ERROR "&yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020047}
48
Luuk van Dijkb536adb2011-10-08 19:37:06 +020049func foo6(xx **int, yy *int) { // ERROR "xx does not escape" "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020050 *xx = yy
51}
52
Russ Coxdb5f9da2011-08-28 12:05:00 -040053func foo7(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020054 **xx = *yy
55}
56
Russ Coxdb5f9da2011-08-28 12:05:00 -040057func foo8(xx, yy *int) int { // ERROR "xx does not escape" "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020058 xx = yy
59 return *xx
60}
61
Luuk van Dijkb536adb2011-10-08 19:37:06 +020062func foo9(xx, yy *int) *int { // ERROR "leaking param: xx" "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020063 xx = yy
64 return xx
65}
66
Russ Coxdb5f9da2011-08-28 12:05:00 -040067func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020068 *xx = *yy
69}
70
71func foo11() int {
72 x, y := 0, 42
Russ Coxb4df33a2011-11-01 11:02:43 -040073 xx := &x // ERROR "&x does not escape"
74 yy := &y // ERROR "&y does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020075 *xx = *yy
76 return x
77}
78
Luuk van Dijk847b61b2011-08-24 19:07:08 +020079var xxx **int
80
Luuk van Dijkb536adb2011-10-08 19:37:06 +020081func foo12(yyy **int) { // ERROR "leaking param: yyy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020082 xxx = yyy
83}
84
Russ Coxc99dce22014-05-09 15:40:45 -040085// Must treat yyy as leaking because *yyy leaks, and the escape analysis
Rémy Oudompheng20c7e412013-03-15 09:03:45 +010086// summaries in exported metadata do not distinguish these two cases.
87func foo13(yyy **int) { // ERROR "leaking param: yyy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020088 *xxx = *yyy
89}
90
Russ Coxdb5f9da2011-08-28 12:05:00 -040091func foo14(yyy **int) { // ERROR "yyy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020092 **xxx = **yyy
93}
94
Luuk van Dijkb536adb2011-10-08 19:37:06 +020095func foo15(yy *int) { // ERROR "moved to heap: yy"
Russ Coxb4df33a2011-11-01 11:02:43 -040096 xxx = &yy // ERROR "&yy escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020097}
98
Luuk van Dijkb536adb2011-10-08 19:37:06 +020099func foo16(yy *int) { // ERROR "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200100 *xxx = yy
101}
102
Russ Coxdb5f9da2011-08-28 12:05:00 -0400103func foo17(yy *int) { // ERROR "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200104 **xxx = *yy
105}
106
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200107func foo18(y int) { // ERROR "moved to heap: "y"
Russ Coxb4df33a2011-11-01 11:02:43 -0400108 *xxx = &y // ERROR "&y escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200109}
110
111func foo19(y int) {
112 **xxx = y
113}
114
115type Bar struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400116 i int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200117 ii *int
118}
119
120func NewBar() *Bar {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200121 return &Bar{42, nil} // ERROR "&Bar literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200122}
123
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200124func NewBarp(x *int) *Bar { // ERROR "leaking param: x"
125 return &Bar{42, x} // ERROR "&Bar literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200126}
127
Russ Coxdb5f9da2011-08-28 12:05:00 -0400128func NewBarp2(x *int) *Bar { // ERROR "x does not escape"
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200129 return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200130}
131
Russ Coxdb5f9da2011-08-28 12:05:00 -0400132func (b *Bar) NoLeak() int { // ERROR "b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200133 return *(b.ii)
134}
135
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100136func (b *Bar) Leak() *int { // ERROR "leaking param: b"
137 return &b.i // ERROR "&b.i escapes to heap"
138}
139
Russ Coxfe3c9132014-06-03 11:35:59 -0400140func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param b content to result ~r0"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200141 return b.ii
142}
143
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100144func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b"
145 return b.ii
146}
147
148func (b Bar) LeaksToo() *int { // ERROR "leaking param: b"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +0100149 v := 0 // ERROR "moved to heap: v"
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100150 b.ii = &v // ERROR "&v escapes"
151 return b.ii
152}
153
Russ Coxfe3c9132014-06-03 11:35:59 -0400154func (b *Bar) LeaksABit() *int { // ERROR "leaking param b content to result ~r0"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +0100155 v := 0 // ERROR "moved to heap: v"
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100156 b.ii = &v // ERROR "&v escapes"
157 return b.ii
158}
159
160func (b Bar) StillNoLeak() int { // ERROR "b does not escape"
161 v := 0
162 b.ii = &v // ERROR "&v does not escape"
163 return b.i
164}
165
Russ Coxb4df33a2011-11-01 11:02:43 -0400166func goLeak(b *Bar) { // ERROR "leaking param: b"
Luuk van Dijkf2460a82011-09-07 19:03:11 +0200167 go b.NoLeak()
168}
169
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200170type Bar2 struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400171 i [12]int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200172 ii []int
173}
174
175func NewBar2() *Bar2 {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200176 return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200177}
178
Russ Coxdb5f9da2011-08-28 12:05:00 -0400179func (b *Bar2) NoLeak() int { // ERROR "b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200180 return b.i[0]
181}
182
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200183func (b *Bar2) Leak() []int { // ERROR "leaking param: b"
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100184 return b.i[:] // ERROR "b.i escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200185}
186
Russ Coxfe3c9132014-06-03 11:35:59 -0400187func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param b content to result ~r0"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200188 return b.ii[0:1]
189}
190
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100191func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape"
192 return b.i
193}
194
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200195func (b *Bar2) LeakSelf() { // ERROR "leaking param: b"
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100196 b.ii = b.i[0:4] // ERROR "b.i escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200197}
198
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200199func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200200 var buf []int
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100201 buf = b.i[0:] // ERROR "b.i escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200202 b.ii = buf
203}
204
205func foo21() func() int {
Russ Coxb4df33a2011-11-01 11:02:43 -0400206 x := 42 // ERROR "moved to heap: x"
207 return func() int { // ERROR "func literal escapes to heap"
208 return x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200209 }
210}
211
212func foo22() int {
213 x := 42
Russ Coxb4df33a2011-11-01 11:02:43 -0400214 return func() int { // ERROR "func literal does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200215 return x
216 }()
217}
218
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200219func foo23(x int) func() int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400220 return func() int { // ERROR "func literal escapes to heap"
221 return x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200222 }
223}
224
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200225func foo23a(x int) func() int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400226 f := func() int { // ERROR "func literal escapes to heap"
227 return x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200228 }
229 return f
230}
231
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200232func foo23b(x int) *(func() int) { // ERROR "moved to heap: x"
233 f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" "&x escapes to heap"
Russ Coxb4df33a2011-11-01 11:02:43 -0400234 return &f // ERROR "&f escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200235}
236
237func foo24(x int) int {
Russ Coxb4df33a2011-11-01 11:02:43 -0400238 return func() int { // ERROR "func literal does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200239 return x
240 }()
241}
242
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200243var x *int
244
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200245func fooleak(xx *int) int { // ERROR "leaking param: xx"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200246 x = xx
247 return *x
248}
249
Russ Coxdb5f9da2011-08-28 12:05:00 -0400250func foonoleak(xx *int) int { // ERROR "xx does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200251 return *x + *xx
252}
253
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200254func foo31(x int) int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400255 return fooleak(&x) // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200256}
257
258func foo32(x int) int {
Russ Coxb4df33a2011-11-01 11:02:43 -0400259 return foonoleak(&x) // ERROR "&x does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200260}
261
262type Foo struct {
263 xx *int
Russ Coxdb5f9da2011-08-28 12:05:00 -0400264 x int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200265}
266
267var F Foo
268var pf *Foo
269
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200270func (f *Foo) fooleak() { // ERROR "leaking param: f"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200271 pf = f
272}
273
Russ Coxdb5f9da2011-08-28 12:05:00 -0400274func (f *Foo) foonoleak() { // ERROR "f does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200275 F.x = f.x
276}
277
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200278func (f *Foo) Leak() { // ERROR "leaking param: f"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200279 f.fooleak()
280}
281
Russ Coxdb5f9da2011-08-28 12:05:00 -0400282func (f *Foo) NoLeak() { // ERROR "f does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200283 f.foonoleak()
284}
285
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200286func foo41(x int) { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400287 F.xx = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200288}
289
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200290func (f *Foo) foo42(x int) { // ERROR "f does not escape" "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400291 f.xx = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200292}
293
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200294func foo43(f *Foo, x int) { // ERROR "f does not escape" "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400295 f.xx = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200296}
297
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200298func foo44(yy *int) { // ERROR "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200299 F.xx = yy
300}
301
Russ Coxdb5f9da2011-08-28 12:05:00 -0400302func (f *Foo) foo45() { // ERROR "f does not escape"
303 F.x = f.x
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200304}
305
Rémy Oudompheng20c7e412013-03-15 09:03:45 +0100306// See foo13 above for explanation of why f leaks.
307func (f *Foo) foo46() { // ERROR "leaking param: f"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400308 F.xx = f.xx
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200309}
310
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200311func (f *Foo) foo47() { // ERROR "leaking param: f"
Russ Coxb4df33a2011-11-01 11:02:43 -0400312 f.xx = &f.x // ERROR "&f.x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200313}
314
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200315var ptrSlice []*int
316
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200317func foo50(i *int) { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200318 ptrSlice[0] = i
319}
320
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200321var ptrMap map[*int]*int
322
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200323func foo51(i *int) { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200324 ptrMap[i] = i
325}
326
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200327func indaddr1(x int) *int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400328 return &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200329}
330
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200331func indaddr2(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400332 return *&x // ERROR "&x does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200333}
334
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200335func indaddr3(x *int32) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400336 return *(**int)(unsafe.Pointer(&x)) // ERROR "&x does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200337}
338
339// From package math:
340
341func Float32bits(f float32) uint32 {
Russ Coxb4df33a2011-11-01 11:02:43 -0400342 return *(*uint32)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200343}
344
345func Float32frombits(b uint32) float32 {
Russ Coxb4df33a2011-11-01 11:02:43 -0400346 return *(*float32)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200347}
348
349func Float64bits(f float64) uint64 {
Russ Coxb4df33a2011-11-01 11:02:43 -0400350 return *(*uint64)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200351}
352
353func Float64frombits(b uint64) float64 {
Russ Coxb4df33a2011-11-01 11:02:43 -0400354 return *(*float64)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200355}
356
357// contrast with
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200358func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f"
Russ Coxb4df33a2011-11-01 11:02:43 -0400359 return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200360}
361
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200362func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200363 return (*uint64)(unsafe.Pointer(f))
364}
365
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200366func typesw(i interface{}) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200367 switch val := i.(type) {
368 case *int:
369 return val
370 case *int8:
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200371 v := int(*val) // ERROR "moved to heap: v"
Russ Coxb4df33a2011-11-01 11:02:43 -0400372 return &v // ERROR "&v escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200373 }
374 return nil
375}
376
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200377func exprsw(i *int) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200378 switch j := i; *j + 110 {
379 case 12:
380 return j
381 case 42:
382 return nil
383 }
384 return nil
385
386}
387
388// assigning to an array element is like assigning to the array
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200389func foo60(i *int) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200390 var a [12]*int
391 a[0] = i
392 return a[1]
393}
394
Russ Coxdb5f9da2011-08-28 12:05:00 -0400395func foo60a(i *int) *int { // ERROR "i does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200396 var a [12]*int
397 a[0] = i
398 return nil
399}
400
401// assigning to a struct field is like assigning to the struct
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200402func foo61(i *int) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200403 type S struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400404 a, b *int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200405 }
406 var s S
407 s.a = i
408 return s.b
409}
410
Russ Coxdb5f9da2011-08-28 12:05:00 -0400411func foo61a(i *int) *int { // ERROR "i does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200412 type S struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400413 a, b *int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200414 }
415 var s S
416 s.a = i
417 return nil
418}
419
420// assigning to a struct field is like assigning to the struct but
421// here this subtlety is lost, since s.a counts as an assignment to a
422// track-losing dereference.
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200423func foo62(i *int) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200424 type S struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400425 a, b *int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200426 }
Russ Coxdb5f9da2011-08-28 12:05:00 -0400427 s := new(S) // ERROR "new[(]S[)] does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200428 s.a = i
Russ Coxdb5f9da2011-08-28 12:05:00 -0400429 return nil // s.b
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200430}
431
Russ Coxdb5f9da2011-08-28 12:05:00 -0400432type M interface {
433 M()
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200434}
435
Russ Coxdb5f9da2011-08-28 12:05:00 -0400436func foo63(m M) { // ERROR "m does not escape"
437}
438
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200439func foo64(m M) { // ERROR "leaking param: m"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200440 m.M()
441}
442
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200443func foo64b(m M) { // ERROR "leaking param: m"
Luuk van Dijkf2460a82011-09-07 19:03:11 +0200444 defer m.M()
445}
446
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200447type MV int
Russ Coxdb5f9da2011-08-28 12:05:00 -0400448
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200449func (MV) M() {}
450
451func foo65() {
452 var mv MV
Russ Coxb4df33a2011-11-01 11:02:43 -0400453 foo63(&mv) // ERROR "&mv does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200454}
455
456func foo66() {
Russ Coxb4df33a2011-11-01 11:02:43 -0400457 var mv MV // ERROR "moved to heap: mv"
458 foo64(&mv) // ERROR "&mv escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200459}
460
461func foo67() {
462 var mv MV
463 foo63(mv)
464}
465
466func foo68() {
467 var mv MV
Russ Coxdb5f9da2011-08-28 12:05:00 -0400468 foo64(mv) // escapes but it's an int so irrelevant
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200469}
470
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200471func foo69(m M) { // ERROR "leaking param: m"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200472 foo64(m)
473}
474
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200475func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200476 m = mv1
477 foo64(m)
478}
479
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200480func foo71(x *int) []*int { // ERROR "leaking param: x"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200481 var y []*int
482 y = append(y, x)
483 return y
484}
485
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200486func foo71a(x int) []*int { // ERROR "moved to heap: x"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200487 var y []*int
Russ Coxb4df33a2011-11-01 11:02:43 -0400488 y = append(y, &x) // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200489 return y
490}
491
492func foo72() {
493 var x int
494 var y [1]*int
Russ Coxb4df33a2011-11-01 11:02:43 -0400495 y[0] = &x // ERROR "&x does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200496}
497
498func foo72aa() [10]*int {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200499 var x int // ERROR "moved to heap: x"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200500 var y [10]*int
Russ Coxb4df33a2011-11-01 11:02:43 -0400501 y[0] = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200502 return y
503}
504
505func foo72a() {
506 var y [10]*int
507 for i := 0; i < 10; i++ {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400508 // escapes its scope
Russ Coxb4df33a2011-11-01 11:02:43 -0400509 x := i // ERROR "moved to heap: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400510 y[i] = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200511 }
512 return
513}
514
515func foo72b() [10]*int {
516 var y [10]*int
517 for i := 0; i < 10; i++ {
Russ Coxb4df33a2011-11-01 11:02:43 -0400518 x := i // ERROR "moved to heap: x"
519 y[i] = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200520 }
521 return y
522}
523
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200524// issue 2145
525func foo73() {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200526 s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200527 for _, v := range s {
Russ Coxb4df33a2011-11-01 11:02:43 -0400528 vv := v // ERROR "moved to heap: vv"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400529 // actually just escapes its scope
530 defer func() { // ERROR "func literal escapes to heap"
Russ Coxb4df33a2011-11-01 11:02:43 -0400531 println(vv) // ERROR "&vv escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200532 }()
533 }
534}
535
536func foo74() {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200537 s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200538 for _, v := range s {
Russ Coxb4df33a2011-11-01 11:02:43 -0400539 vv := v // ERROR "moved to heap: vv"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400540 // actually just escapes its scope
541 fn := func() { // ERROR "func literal escapes to heap"
Russ Coxb4df33a2011-11-01 11:02:43 -0400542 println(vv) // ERROR "&vv escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200543 }
544 defer fn()
545 }
546}
547
Rémy Oudomphengba97d522012-08-31 22:23:37 +0200548// issue 3975
549func foo74b() {
550 var array [3]func()
551 s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
552 for i, v := range s {
553 vv := v // ERROR "moved to heap: vv"
554 // actually just escapes its scope
555 array[i] = func() { // ERROR "func literal escapes to heap"
556 println(vv) // ERROR "&vv escapes to heap"
557 }
558 }
559}
560
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200561func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200562 return y
563}
564
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200565func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400566 return &x[0] // ERROR "&x.0. escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200567}
568
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100569func foo75(z *int) { // ERROR "z does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400570 myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200571}
572
Russ Coxdb5f9da2011-08-28 12:05:00 -0400573func foo75a(z *int) { // ERROR "z does not escape"
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100574 myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
575}
576
577func foo75esc(z *int) { // ERROR "leaking param: z"
578 gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
579}
580
581func foo75aesc(z *int) { // ERROR "z does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +0100582 var ppi **interface{} // assignments to pointer dereferences lose track
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100583 *ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200584}
585
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200586func foo76(z *int) { // ERROR "leaking param: z"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400587 myprint(nil, z) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200588}
589
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200590func foo76a(z *int) { // ERROR "leaking param: z"
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100591 myprint1(nil, z) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200592}
593
594func foo76b() {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400595 myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200596}
597
598func foo76c() {
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100599 myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200600}
601
602func foo76d() {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400603 defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200604}
605
606func foo76e() {
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100607 defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200608}
609
610func foo76f() {
611 for {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400612 // TODO: This one really only escapes its scope, but we don't distinguish yet.
613 defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200614 }
615}
616
617func foo76g() {
618 for {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400619 defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200620 }
621}
622
Russ Coxdb5f9da2011-08-28 12:05:00 -0400623func foo77(z []interface{}) { // ERROR "z does not escape"
624 myprint(nil, z...) // z does not escape
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200625}
626
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100627func foo77a(z []interface{}) { // ERROR "z does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200628 myprint1(nil, z...)
629}
630
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100631func foo77b(z []interface{}) { // ERROR "leaking param: z"
632 var ppi **interface{}
633 *ppi = myprint1(nil, z...)
634}
635
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200636func foo78(z int) *int { // ERROR "moved to heap: z"
Russ Coxb4df33a2011-11-01 11:02:43 -0400637 return &z // ERROR "&z escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200638}
639
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200640func foo78a(z int) *int { // ERROR "moved to heap: z"
Russ Coxb4df33a2011-11-01 11:02:43 -0400641 y := &z // ERROR "&z escapes to heap"
642 x := &y // ERROR "&y does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400643 return *x // really return y
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200644}
645
646func foo79() *int {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400647 return new(int) // ERROR "new[(]int[)] escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200648}
649
650func foo80() *int {
651 var z *int
652 for {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400653 // Really just escapes its scope but we don't distinguish
654 z = new(int) // ERROR "new[(]int[)] escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200655 }
656 _ = z
657 return nil
658}
659
660func foo81() *int {
661 for {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400662 z := new(int) // ERROR "new[(]int[)] does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200663 _ = z
664 }
665 return nil
666}
667
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +0100668func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param"
669
670func noop(x, y *int) {} // ERROR "does not escape"
671
672func foo82() {
673 var x, y, z int // ERROR "moved to heap"
674 go noop(tee(&z)) // ERROR "&z escapes to heap"
675 go noop(&x, &y) // ERROR "escapes to heap"
676 for {
677 var u, v, w int // ERROR "moved to heap"
678 defer noop(tee(&u)) // ERROR "&u escapes to heap"
679 defer noop(&v, &w) // ERROR "escapes to heap"
680 }
681}
682
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200683type Fooer interface {
684 Foo()
685}
686
687type LimitedFooer struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400688 Fooer
689 N int64
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200690}
691
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200692func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r"
693 return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200694}
695
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200696func foo90(x *int) map[*int]*int { // ERROR "leaking param: x"
Russ Cox434a6c82011-12-02 14:45:07 -0500697 return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200698}
699
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200700func foo91(x *int) map[*int]*int { // ERROR "leaking param: x"
Russ Cox434a6c82011-12-02 14:45:07 -0500701 return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200702}
703
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200704func foo92(x *int) [2]*int { // ERROR "leaking param: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400705 return [2]*int{x, nil}
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200706}
707
Russ Cox0227c452011-08-25 09:26:13 -0400708// does not leak c
Russ Coxdb5f9da2011-08-28 12:05:00 -0400709func foo93(c chan *int) *int { // ERROR "c does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400710 for v := range c {
711 return v
712 }
713 return nil
714}
715
716// does not leak m
Russ Coxdb5f9da2011-08-28 12:05:00 -0400717func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400718 for k, v := range m {
719 if b {
720 return k
721 }
722 return v
723 }
724 return nil
725}
726
727// does leak x
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200728func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape" "leaking param: x"
Russ Cox0227c452011-08-25 09:26:13 -0400729 m[x] = x
730}
731
732// does not leak m
Russ Coxdb5f9da2011-08-28 12:05:00 -0400733func foo96(m []*int) *int { // ERROR "m does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400734 return m[0]
735}
736
737// does leak m
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200738func foo97(m [1]*int) *int { // ERROR "leaking param: m"
Russ Cox0227c452011-08-25 09:26:13 -0400739 return m[0]
740}
741
742// does not leak m
Russ Coxdb5f9da2011-08-28 12:05:00 -0400743func foo98(m map[int]*int) *int { // ERROR "m does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400744 return m[0]
745}
746
747// does leak m
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200748func foo99(m *[1]*int) []*int { // ERROR "leaking param: m"
Russ Cox0227c452011-08-25 09:26:13 -0400749 return m[:]
750}
751
752// does not leak m
Russ Coxdb5f9da2011-08-28 12:05:00 -0400753func foo100(m []*int) *int { // ERROR "m does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400754 for _, v := range m {
755 return v
756 }
757 return nil
758}
759
760// does leak m
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200761func foo101(m [1]*int) *int { // ERROR "leaking param: m"
Russ Cox0227c452011-08-25 09:26:13 -0400762 for _, v := range m {
763 return v
764 }
765 return nil
766}
767
Russ Coxdb5f9da2011-08-28 12:05:00 -0400768// does not leak m
769func foo101a(m [1]*int) *int { // ERROR "m does not escape"
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200770 for i := range m { // ERROR "moved to heap: i"
Russ Coxb4df33a2011-11-01 11:02:43 -0400771 return &i // ERROR "&i escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400772 }
773 return nil
774}
775
Russ Cox0227c452011-08-25 09:26:13 -0400776// does leak x
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200777func foo102(m []*int, x *int) { // ERROR "m does not escape" "leaking param: x"
Russ Cox0227c452011-08-25 09:26:13 -0400778 m[0] = x
779}
780
781// does not leak x
Russ Coxdb5f9da2011-08-28 12:05:00 -0400782func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400783 m[0] = x
784}
785
786var y []*int
787
788// does not leak x
Russ Coxb4df33a2011-11-01 11:02:43 -0400789func foo104(x []*int) { // ERROR "x does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400790 copy(y, x)
791}
792
793// does not leak x
Russ Coxb4df33a2011-11-01 11:02:43 -0400794func foo105(x []*int) { // ERROR "x does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400795 _ = append(y, x...)
796}
797
798// does leak x
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200799func foo106(x *int) { // ERROR "leaking param: x"
Russ Cox0227c452011-08-25 09:26:13 -0400800 _ = append(y, x)
801}
Russ Coxdb5f9da2011-08-28 12:05:00 -0400802
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200803func foo107(x *int) map[*int]*int { // ERROR "leaking param: x"
804 return map[*int]*int{x: nil} // ERROR "map.* literal escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400805}
806
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200807func foo108(x *int) map[*int]*int { // ERROR "leaking param: x"
808 return map[*int]*int{nil: x} // ERROR "map.* literal escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400809}
810
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200811func foo109(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400812 m := map[*int]*int{x: nil} // ERROR "map.* literal does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400813 for k, _ := range m {
814 return k
815 }
816 return nil
817}
818
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200819func foo110(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400820 m := map[*int]*int{nil: x} // ERROR "map.* literal does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400821 return m[nil]
822}
823
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200824func foo111(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400825 m := []*int{x} // ERROR "\[\]\*int literal does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400826 return m[0]
827}
828
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200829func foo112(x *int) *int { // ERROR "leaking param: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400830 m := [1]*int{x}
831 return m[0]
832}
833
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200834func foo113(x *int) *int { // ERROR "leaking param: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400835 m := Bar{ii: x}
836 return m.ii
837}
838
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200839func foo114(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400840 m := &Bar{ii: x} // ERROR "&Bar literal does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400841 return m.ii
842}
843
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200844func foo115(x *int) *int { // ERROR "leaking param: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400845 return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
846}
847
848func foo116(b bool) *int {
849 if b {
Russ Coxb4df33a2011-11-01 11:02:43 -0400850 x := 1 // ERROR "moved to heap: x"
851 return &x // ERROR "&x escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400852 } else {
Russ Coxb4df33a2011-11-01 11:02:43 -0400853 y := 1 // ERROR "moved to heap: y"
854 return &y // ERROR "&y escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400855 }
856 return nil
857}
858
Russ Coxb4df33a2011-11-01 11:02:43 -0400859func foo117(unknown func(interface{})) { // ERROR "unknown does not escape"
860 x := 1 // ERROR "moved to heap: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400861 unknown(&x) // ERROR "&x escapes to heap"
862}
863
Russ Coxb4df33a2011-11-01 11:02:43 -0400864func foo118(unknown func(*int)) { // ERROR "unknown does not escape"
865 x := 1 // ERROR "moved to heap: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400866 unknown(&x) // ERROR "&x escapes to heap"
867}
Russ Cox77f0bdc2011-08-28 23:29:34 -0400868
869func external(*int)
870
Russ Coxb4df33a2011-11-01 11:02:43 -0400871func foo119(x *int) { // ERROR "leaking param: x"
Russ Cox77f0bdc2011-08-28 23:29:34 -0400872 external(x)
873}
Russ Cox60d47102011-09-01 13:44:46 -0400874
875func foo120() {
876 // formerly exponential time analysis
877L1:
878L2:
879L3:
880L4:
881L5:
882L6:
883L7:
884L8:
885L9:
886L10:
887L11:
888L12:
889L13:
890L14:
891L15:
892L16:
893L17:
894L18:
895L19:
896L20:
897L21:
898L22:
899L23:
900L24:
901L25:
902L26:
903L27:
904L28:
905L29:
906L30:
907L31:
908L32:
909L33:
910L34:
911L35:
912L36:
913L37:
914L38:
915L39:
916L40:
917L41:
918L42:
919L43:
920L44:
921L45:
922L46:
923L47:
924L48:
925L49:
926L50:
927L51:
928L52:
929L53:
930L54:
931L55:
932L56:
933L57:
934L58:
935L59:
936L60:
937L61:
938L62:
939L63:
940L64:
941L65:
942L66:
943L67:
944L68:
945L69:
946L70:
947L71:
948L72:
949L73:
950L74:
951L75:
952L76:
953L77:
954L78:
955L79:
956L80:
957L81:
958L82:
959L83:
960L84:
961L85:
962L86:
963L87:
964L88:
965L89:
966L90:
967L91:
968L92:
969L93:
970L94:
971L95:
972L96:
973L97:
974L98:
975L99:
976L100:
977 // use the labels to silence compiler errors
978 goto L1
979 goto L2
980 goto L3
981 goto L4
982 goto L5
983 goto L6
984 goto L7
985 goto L8
986 goto L9
987 goto L10
988 goto L11
989 goto L12
990 goto L13
991 goto L14
992 goto L15
993 goto L16
994 goto L17
995 goto L18
996 goto L19
997 goto L20
998 goto L21
999 goto L22
1000 goto L23
1001 goto L24
1002 goto L25
1003 goto L26
1004 goto L27
1005 goto L28
1006 goto L29
1007 goto L30
1008 goto L31
1009 goto L32
1010 goto L33
1011 goto L34
1012 goto L35
1013 goto L36
1014 goto L37
1015 goto L38
1016 goto L39
1017 goto L40
1018 goto L41
1019 goto L42
1020 goto L43
1021 goto L44
1022 goto L45
1023 goto L46
1024 goto L47
1025 goto L48
1026 goto L49
1027 goto L50
1028 goto L51
1029 goto L52
1030 goto L53
1031 goto L54
1032 goto L55
1033 goto L56
1034 goto L57
1035 goto L58
1036 goto L59
1037 goto L60
1038 goto L61
1039 goto L62
1040 goto L63
1041 goto L64
1042 goto L65
1043 goto L66
1044 goto L67
1045 goto L68
1046 goto L69
1047 goto L70
1048 goto L71
1049 goto L72
1050 goto L73
1051 goto L74
1052 goto L75
1053 goto L76
1054 goto L77
1055 goto L78
1056 goto L79
1057 goto L80
1058 goto L81
1059 goto L82
1060 goto L83
1061 goto L84
1062 goto L85
1063 goto L86
1064 goto L87
1065 goto L88
1066 goto L89
1067 goto L90
1068 goto L91
1069 goto L92
1070 goto L93
1071 goto L94
1072 goto L95
1073 goto L96
1074 goto L97
1075 goto L98
1076 goto L99
1077 goto L100
1078}
Russ Coxb4df33a2011-11-01 11:02:43 -04001079
1080func foo121() {
1081 for i := 0; i < 10; i++ {
1082 defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
1083 go myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
1084 }
1085}
1086
1087// same as foo121 but check across import
1088func foo121b() {
1089 for i := 0; i < 10; i++ {
1090 defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
1091 go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
1092 }
1093}
Luuk van Dijk9bf34782011-12-15 17:35:59 +01001094
1095// a harmless forward jump
1096func foo122() {
1097 var i *int
1098
1099 goto L1
1100L1:
Luuk van Dijk55830602012-04-23 15:39:01 -04001101 i = new(int) // ERROR "new.int. does not escape"
Luuk van Dijk9bf34782011-12-15 17:35:59 +01001102 _ = i
1103}
1104
1105// a backward jump, increases loopdepth
1106func foo123() {
1107 var i *int
1108
1109L1:
Luuk van Dijk55830602012-04-23 15:39:01 -04001110 i = new(int) // ERROR "new.int. escapes to heap"
Luuk van Dijk9bf34782011-12-15 17:35:59 +01001111
1112 goto L1
1113 _ = i
Rémy Oudompheng94ff3112012-01-12 12:08:40 +01001114}
Luuk van Dijk55830602012-04-23 15:39:01 -04001115
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001116func foo124(x **int) { // ERROR "x does not escape"
1117 var i int // ERROR "moved to heap: i"
1118 p := &i // ERROR "&i escapes"
1119 func() { // ERROR "func literal does not escape"
1120 *x = p // ERROR "leaking closure reference p"
Luuk van Dijk55830602012-04-23 15:39:01 -04001121 }()
1122}
1123
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001124func foo125(ch chan *int) { // ERROR "does not escape"
1125 var i int // ERROR "moved to heap"
1126 p := &i // ERROR "&i escapes to heap"
1127 func() { // ERROR "func literal does not escape"
1128 ch <- p // ERROR "leaking closure reference p"
Luuk van Dijk55830602012-04-23 15:39:01 -04001129 }()
1130}
1131
1132func foo126() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001133 var px *int // loopdepth 0
Luuk van Dijk55830602012-04-23 15:39:01 -04001134 for {
1135 // loopdepth 1
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001136 var i int // ERROR "moved to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001137 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001138 px = &i // ERROR "&i escapes"
Luuk van Dijk55830602012-04-23 15:39:01 -04001139 }()
1140 }
Robert Griesemer99d87722013-09-17 15:24:54 -07001141 _ = px
Luuk van Dijk55830602012-04-23 15:39:01 -04001142}
1143
1144var px *int
1145
1146func foo127() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001147 var i int // ERROR "moved to heap: i"
1148 p := &i // ERROR "&i escapes to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001149 q := p
1150 px = q
1151}
1152
1153func foo128() {
1154 var i int
1155 p := &i // ERROR "&i does not escape"
1156 q := p
1157 _ = q
1158}
1159
1160func foo129() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001161 var i int // ERROR "moved to heap: i"
1162 p := &i // ERROR "&i escapes to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001163 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001164 q := p // ERROR "leaking closure reference p"
1165 func() { // ERROR "func literal does not escape"
1166 r := q // ERROR "leaking closure reference q"
Luuk van Dijk55830602012-04-23 15:39:01 -04001167 px = r
1168 }()
1169 }()
1170}
1171
1172func foo130() {
1173 for {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001174 var i int // ERROR "moved to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001175 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001176 px = &i // ERROR "&i escapes" "leaking closure reference i"
Luuk van Dijk55830602012-04-23 15:39:01 -04001177 }()
1178 }
1179}
1180
1181func foo131() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001182 var i int // ERROR "moved to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001183 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001184 px = &i // ERROR "&i escapes" "leaking closure reference i"
Luuk van Dijk55830602012-04-23 15:39:01 -04001185 }()
1186}
1187
1188func foo132() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001189 var i int // ERROR "moved to heap"
1190 go func() { // ERROR "func literal escapes to heap"
1191 px = &i // ERROR "&i escapes" "leaking closure reference i"
Luuk van Dijk55830602012-04-23 15:39:01 -04001192 }()
1193}
1194
1195func foo133() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001196 var i int // ERROR "moved to heap"
1197 defer func() { // ERROR "func literal does not escape"
1198 px = &i // ERROR "&i escapes" "leaking closure reference i"
Luuk van Dijk55830602012-04-23 15:39:01 -04001199 }()
1200}
1201
1202func foo134() {
1203 var i int
1204 p := &i // ERROR "&i does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001205 func() { // ERROR "func literal does not escape"
Luuk van Dijk55830602012-04-23 15:39:01 -04001206 q := p
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001207 func() { // ERROR "func literal does not escape"
Luuk van Dijk55830602012-04-23 15:39:01 -04001208 r := q
1209 _ = r
1210 }()
1211 }()
1212}
1213
1214func foo135() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001215 var i int // ERROR "moved to heap: i"
1216 p := &i // ERROR "&i escapes to heap" "moved to heap: p"
1217 go func() { // ERROR "func literal escapes to heap"
1218 q := p // ERROR "&p escapes to heap"
1219 func() { // ERROR "func literal does not escape"
Luuk van Dijk55830602012-04-23 15:39:01 -04001220 r := q
1221 _ = r
1222 }()
1223 }()
1224}
1225
1226func foo136() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001227 var i int // ERROR "moved to heap: i"
1228 p := &i // ERROR "&i escapes to heap" "moved to heap: p"
1229 go func() { // ERROR "func literal escapes to heap"
1230 q := p // ERROR "&p escapes to heap" "leaking closure reference p"
1231 func() { // ERROR "func literal does not escape"
Luuk van Dijk55830602012-04-23 15:39:01 -04001232 r := q // ERROR "leaking closure reference q"
1233 px = r
1234 }()
1235 }()
1236}
1237
1238func foo137() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001239 var i int // ERROR "moved to heap: i"
1240 p := &i // ERROR "&i escapes to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001241 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001242 q := p // ERROR "leaking closure reference p" "moved to heap: q"
Luuk van Dijk55830602012-04-23 15:39:01 -04001243 go func() { // ERROR "func literal escapes to heap"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001244 r := q // ERROR "&q escapes to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001245 _ = r
1246 }()
1247 }()
1248}
Russ Cox54af7522012-09-24 15:53:12 -04001249
1250func foo138() *byte {
1251 type T struct {
1252 x [1]byte
1253 }
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001254 t := new(T) // ERROR "new.T. escapes to heap"
Russ Cox54af7522012-09-24 15:53:12 -04001255 return &t.x[0] // ERROR "&t.x.0. escapes to heap"
1256}
1257
1258func foo139() *byte {
1259 type T struct {
1260 x struct {
1261 y byte
1262 }
1263 }
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001264 t := new(T) // ERROR "new.T. escapes to heap"
Russ Cox54af7522012-09-24 15:53:12 -04001265 return &t.x.y // ERROR "&t.x.y escapes to heap"
1266}
Russ Cox572d9842013-02-04 22:48:31 -05001267
1268// issue 4751
1269func foo140() interface{} {
1270 type T struct {
1271 X string
1272 }
1273 type U struct {
1274 X string
1275 T *T
1276 }
1277 t := &T{} // ERROR "&T literal escapes to heap"
1278 return U{
1279 X: t.X,
1280 T: t,
1281 }
1282}
Russ Coxfd178d62013-02-05 07:00:38 -05001283
1284//go:noescape
1285
1286func F1([]byte)
1287
1288func F2([]byte)
1289
1290//go:noescape
1291
1292func F3(x []byte) // ERROR "F3 x does not escape"
1293
1294func F4(x []byte)
1295
1296func G() {
1297 var buf1 [10]byte
1298 F1(buf1[:]) // ERROR "buf1 does not escape"
Russ Coxc99dce22014-05-09 15:40:45 -04001299
Russ Coxfd178d62013-02-05 07:00:38 -05001300 var buf2 [10]byte // ERROR "moved to heap: buf2"
Russ Coxc99dce22014-05-09 15:40:45 -04001301 F2(buf2[:]) // ERROR "buf2 escapes to heap"
Russ Coxfd178d62013-02-05 07:00:38 -05001302
1303 var buf3 [10]byte
1304 F3(buf3[:]) // ERROR "buf3 does not escape"
Russ Coxc99dce22014-05-09 15:40:45 -04001305
Russ Coxfd178d62013-02-05 07:00:38 -05001306 var buf4 [10]byte // ERROR "moved to heap: buf4"
Russ Coxc99dce22014-05-09 15:40:45 -04001307 F4(buf4[:]) // ERROR "buf4 escapes to heap"
Russ Coxfd178d62013-02-05 07:00:38 -05001308}
Russ Cox38e9b072013-03-20 23:53:27 -04001309
1310type Tm struct {
1311 x int
1312}
1313
1314func (t *Tm) M() { // ERROR "t does not escape"
1315}
1316
1317func foo141() {
1318 var f func()
Russ Coxc99dce22014-05-09 15:40:45 -04001319
Russ Cox38e9b072013-03-20 23:53:27 -04001320 t := new(Tm) // ERROR "escapes to heap"
Russ Coxc99dce22014-05-09 15:40:45 -04001321 f = t.M // ERROR "t.M does not escape"
Russ Cox38e9b072013-03-20 23:53:27 -04001322 _ = f
1323}
1324
1325var gf func()
1326
1327func foo142() {
1328 t := new(Tm) // ERROR "escapes to heap"
Russ Coxc99dce22014-05-09 15:40:45 -04001329 gf = t.M // ERROR "t.M escapes to heap"
Russ Cox38e9b072013-03-20 23:53:27 -04001330}
Rémy Oudompheng35773982013-05-22 22:45:38 +02001331
1332// issue 3888.
1333func foo143() {
1334 for i := 0; i < 1000; i++ {
1335 func() { // ERROR "func literal does not escape"
1336 for i := 0; i < 1; i++ {
1337 var t Tm
1338 t.M() // ERROR "t does not escape"
1339 }
1340 }()
1341 }
1342}
Russ Cox148fac72013-06-25 17:28:49 -04001343
1344// issue 5773
1345// Check that annotations take effect regardless of whether they
1346// are before or after the use in the source code.
1347
1348//go:noescape
1349
1350func foo144a(*int)
1351
1352func foo144() {
1353 var x int
1354 foo144a(&x) // ERROR "&x does not escape"
1355 var y int
1356 foo144b(&y) // ERROR "&y does not escape"
1357}
1358
1359//go:noescape
1360
1361func foo144b(*int)
Daniel Morsinge0a55a62014-02-13 19:04:43 +00001362
1363// issue 7313: for loop init should not be treated as "in loop"
1364
1365type List struct {
1366 Next *List
1367}
1368
1369func foo145(l List) { // ERROR "l does not escape"
1370 var p *List
1371 for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
1372 }
1373}
1374
1375func foo146(l List) { // ERROR "l does not escape"
1376 var p *List
1377 p = &l // ERROR "&l does not escape"
1378 for ; p.Next != nil; p = p.Next {
1379 }
1380}
1381
1382func foo147(l List) { // ERROR "l does not escape"
1383 var p *List
1384 p = &l // ERROR "&l does not escape"
1385 for p.Next != nil {
1386 p = p.Next
1387 }
1388}
1389
1390func foo148(l List) { // ERROR " l does not escape"
1391 for p := &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
1392 }
1393}
Russ Coxe5d742f2014-02-13 19:59:09 -05001394
1395// related: address of variable should have depth of variable, not of loop
1396
1397func foo149(l List) { // ERROR " l does not escape"
1398 var p *List
1399 for {
1400 for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
1401 }
1402 }
1403}
Russ Coxc99dce22014-05-09 15:40:45 -04001404
1405// issue 7934: missed ... if element type had no pointers
1406
1407var save150 []byte
1408
1409func foo150(x ...byte) { // ERROR "leaking param: x"
1410 save150 = x
1411}
1412
1413func bar150() {
1414 foo150(1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
1415}
Russ Coxf0787112014-05-12 14:45:05 -04001416
1417// issue 7931: bad handling of slice of array
1418
1419var save151 *int
1420
1421func foo151(x *int) { // ERROR "leaking param: x"
1422 save151 = x
1423}
1424
1425func bar151() {
1426 var a [64]int // ERROR "moved to heap: a"
1427 a[4] = 101
1428 foo151(&(&a)[4:8][0]) // ERROR "&\(&a\)\[4:8\]\[0\] escapes to heap" "&a escapes to heap"
1429}
1430
1431func bar151b() {
1432 var a [10]int // ERROR "moved to heap: a"
1433 b := a[:] // ERROR "a escapes to heap"
1434 foo151(&b[4:8][0]) // ERROR "&b\[4:8\]\[0\] escapes to heap"
1435}
1436
1437func bar151c() {
1438 var a [64]int // ERROR "moved to heap: a"
1439 a[4] = 101
1440 foo151(&(&a)[4:8:8][0]) // ERROR "&\(&a\)\[4:8:8\]\[0\] escapes to heap" "&a escapes to heap"
1441}
1442
1443func bar151d() {
1444 var a [10]int // ERROR "moved to heap: a"
1445 b := a[:] // ERROR "a escapes to heap"
1446 foo151(&b[4:8:8][0]) // ERROR "&b\[4:8:8\]\[0\] escapes to heap"
1447}
Russ Coxfe3c9132014-06-03 11:35:59 -04001448
1449// issue 8120
1450
1451type U struct {
1452 s *string
1453}
1454
1455func (u *U) String() *string { // ERROR "leaking param u content to result ~r0"
1456 return u.s
1457}
1458
1459type V struct {
1460 s *string
1461}
1462
1463func NewV(u U) *V { // ERROR "leaking param: u"
1464 return &V{u.String()} // ERROR "&V literal escapes to heap" "u does not escape"
1465}
1466
1467func foo152() {
1468 a := "a" // ERROR "moved to heap: a"
1469 u := U{&a} // ERROR "&a escapes to heap"
1470 v := NewV(u)
1471 println(v)
1472}
Russ Cox775ab8e2014-06-11 11:48:47 -04001473
1474// issue 8176 - &x in type switch body not marked as escaping
1475
1476func foo153(v interface{}) *int { // ERROR "leaking param: v"
1477 switch x := v.(type) {
1478 case int: // ERROR "moved to heap: x"
1479 return &x // ERROR "&x escapes to heap"
1480 }
1481 panic(0)
1482}
Russ Coxf20e4d52014-06-11 14:21:06 -04001483
1484// issue 8185 - &result escaping into result
1485
1486func f() (x int, y *int) { // ERROR "moved to heap: x"
1487 y = &x // ERROR "&x escapes to heap"
1488 return
1489}
1490
1491func g() (x interface{}) { // ERROR "moved to heap: x"
1492 x = &x // ERROR "&x escapes to heap"
1493 return
1494}