blob: be89c2d84082b86e517e3a8ab9564b8122abf424 [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
Luuk van Dijk847b61b2011-08-24 19:07:08 +020010package foo
11
Russ Coxb4df33a2011-11-01 11:02:43 -040012import (
13 "fmt"
14 "unsafe"
15)
Luuk van Dijk847b61b2011-08-24 19:07:08 +020016
17var gxx *int
18
Luuk van Dijkb536adb2011-10-08 19:37:06 +020019func foo1(x int) { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -040020 gxx = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020021}
22
Luuk van Dijkb536adb2011-10-08 19:37:06 +020023func foo2(yy *int) { // ERROR "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020024 gxx = yy
25}
26
Luuk van Dijkb536adb2011-10-08 19:37:06 +020027func foo3(x int) *int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -040028 return &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020029}
30
31type T *T
Russ Coxdb5f9da2011-08-28 12:05:00 -040032
Luuk van Dijkb536adb2011-10-08 19:37:06 +020033func foo3b(t T) { // ERROR "leaking param: t"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020034 *t = t
35}
36
37// xx isn't going anywhere, so use of yy is ok
Russ Coxdb5f9da2011-08-28 12:05:00 -040038func foo4(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020039 xx = yy
40}
41
42// xx isn't going anywhere, so taking address of yy is ok
Russ Coxdb5f9da2011-08-28 12:05:00 -040043func foo5(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
Russ Coxb4df33a2011-11-01 11:02:43 -040044 xx = &yy // ERROR "&yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020045}
46
Luuk van Dijkb536adb2011-10-08 19:37:06 +020047func foo6(xx **int, yy *int) { // ERROR "xx does not escape" "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020048 *xx = yy
49}
50
Russ Coxdb5f9da2011-08-28 12:05:00 -040051func foo7(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020052 **xx = *yy
53}
54
Russ Coxdb5f9da2011-08-28 12:05:00 -040055func foo8(xx, yy *int) int { // ERROR "xx does not escape" "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020056 xx = yy
57 return *xx
58}
59
Luuk van Dijkb536adb2011-10-08 19:37:06 +020060func foo9(xx, yy *int) *int { // ERROR "leaking param: xx" "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020061 xx = yy
62 return xx
63}
64
Russ Coxdb5f9da2011-08-28 12:05:00 -040065func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020066 *xx = *yy
67}
68
69func foo11() int {
70 x, y := 0, 42
Russ Coxb4df33a2011-11-01 11:02:43 -040071 xx := &x // ERROR "&x does not escape"
72 yy := &y // ERROR "&y does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020073 *xx = *yy
74 return x
75}
76
Luuk van Dijk847b61b2011-08-24 19:07:08 +020077var xxx **int
78
Luuk van Dijkb536adb2011-10-08 19:37:06 +020079func foo12(yyy **int) { // ERROR "leaking param: yyy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020080 xxx = yyy
81}
82
Rémy Oudompheng20c7e412013-03-15 09:03:45 +010083// Must treat yyy as leaking because *yyy leaks, and the escape analysis
84// summaries in exported metadata do not distinguish these two cases.
85func foo13(yyy **int) { // ERROR "leaking param: yyy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020086 *xxx = *yyy
87}
88
Russ Coxdb5f9da2011-08-28 12:05:00 -040089func foo14(yyy **int) { // ERROR "yyy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020090 **xxx = **yyy
91}
92
Luuk van Dijkb536adb2011-10-08 19:37:06 +020093func foo15(yy *int) { // ERROR "moved to heap: yy"
Russ Coxb4df33a2011-11-01 11:02:43 -040094 xxx = &yy // ERROR "&yy escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020095}
96
Luuk van Dijkb536adb2011-10-08 19:37:06 +020097func foo16(yy *int) { // ERROR "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +020098 *xxx = yy
99}
100
Russ Coxdb5f9da2011-08-28 12:05:00 -0400101func foo17(yy *int) { // ERROR "yy does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200102 **xxx = *yy
103}
104
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200105func foo18(y int) { // ERROR "moved to heap: "y"
Russ Coxb4df33a2011-11-01 11:02:43 -0400106 *xxx = &y // ERROR "&y escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200107}
108
109func foo19(y int) {
110 **xxx = y
111}
112
113type Bar struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400114 i int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200115 ii *int
116}
117
118func NewBar() *Bar {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200119 return &Bar{42, nil} // ERROR "&Bar literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200120}
121
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200122func NewBarp(x *int) *Bar { // ERROR "leaking param: x"
123 return &Bar{42, x} // ERROR "&Bar literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200124}
125
Russ Coxdb5f9da2011-08-28 12:05:00 -0400126func NewBarp2(x *int) *Bar { // ERROR "x does not escape"
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200127 return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200128}
129
Russ Coxdb5f9da2011-08-28 12:05:00 -0400130func (b *Bar) NoLeak() int { // ERROR "b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200131 return *(b.ii)
132}
133
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100134func (b *Bar) Leak() *int { // ERROR "leaking param: b"
135 return &b.i // ERROR "&b.i escapes to heap"
136}
137
Russ Coxdb5f9da2011-08-28 12:05:00 -0400138func (b *Bar) AlsoNoLeak() *int { // ERROR "b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200139 return b.ii
140}
141
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100142func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b"
143 return b.ii
144}
145
146func (b Bar) LeaksToo() *int { // ERROR "leaking param: b"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +0100147 v := 0 // ERROR "moved to heap: v"
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100148 b.ii = &v // ERROR "&v escapes"
149 return b.ii
150}
151
152func (b *Bar) LeaksABit() *int { // ERROR "b does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +0100153 v := 0 // ERROR "moved to heap: v"
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100154 b.ii = &v // ERROR "&v escapes"
155 return b.ii
156}
157
158func (b Bar) StillNoLeak() int { // ERROR "b does not escape"
159 v := 0
160 b.ii = &v // ERROR "&v does not escape"
161 return b.i
162}
163
Russ Coxb4df33a2011-11-01 11:02:43 -0400164func goLeak(b *Bar) { // ERROR "leaking param: b"
Luuk van Dijkf2460a82011-09-07 19:03:11 +0200165 go b.NoLeak()
166}
167
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200168type Bar2 struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400169 i [12]int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200170 ii []int
171}
172
173func NewBar2() *Bar2 {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200174 return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200175}
176
Russ Coxdb5f9da2011-08-28 12:05:00 -0400177func (b *Bar2) NoLeak() int { // ERROR "b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200178 return b.i[0]
179}
180
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200181func (b *Bar2) Leak() []int { // ERROR "leaking param: b"
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100182 return b.i[:] // ERROR "b.i escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200183}
184
Russ Coxdb5f9da2011-08-28 12:05:00 -0400185func (b *Bar2) AlsoNoLeak() []int { // ERROR "b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200186 return b.ii[0:1]
187}
188
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100189func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape"
190 return b.i
191}
192
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200193func (b *Bar2) LeakSelf() { // ERROR "leaking param: b"
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100194 b.ii = b.i[0:4] // ERROR "b.i escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200195}
196
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200197func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200198 var buf []int
Rémy Oudompheng94ff3112012-01-12 12:08:40 +0100199 buf = b.i[0:] // ERROR "b.i escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200200 b.ii = buf
201}
202
203func foo21() func() int {
Russ Coxb4df33a2011-11-01 11:02:43 -0400204 x := 42 // ERROR "moved to heap: x"
205 return func() int { // ERROR "func literal escapes to heap"
206 return x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200207 }
208}
209
210func foo22() int {
211 x := 42
Russ Coxb4df33a2011-11-01 11:02:43 -0400212 return func() int { // ERROR "func literal does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200213 return x
214 }()
215}
216
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200217func foo23(x int) func() int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400218 return func() int { // ERROR "func literal escapes to heap"
219 return x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200220 }
221}
222
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200223func foo23a(x int) func() int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400224 f := func() int { // ERROR "func literal escapes to heap"
225 return x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200226 }
227 return f
228}
229
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200230func foo23b(x int) *(func() int) { // ERROR "moved to heap: x"
231 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 -0400232 return &f // ERROR "&f escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200233}
234
235func foo24(x int) int {
Russ Coxb4df33a2011-11-01 11:02:43 -0400236 return func() int { // ERROR "func literal does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200237 return x
238 }()
239}
240
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200241var x *int
242
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200243func fooleak(xx *int) int { // ERROR "leaking param: xx"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200244 x = xx
245 return *x
246}
247
Russ Coxdb5f9da2011-08-28 12:05:00 -0400248func foonoleak(xx *int) int { // ERROR "xx does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200249 return *x + *xx
250}
251
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200252func foo31(x int) int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400253 return fooleak(&x) // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200254}
255
256func foo32(x int) int {
Russ Coxb4df33a2011-11-01 11:02:43 -0400257 return foonoleak(&x) // ERROR "&x does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200258}
259
260type Foo struct {
261 xx *int
Russ Coxdb5f9da2011-08-28 12:05:00 -0400262 x int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200263}
264
265var F Foo
266var pf *Foo
267
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200268func (f *Foo) fooleak() { // ERROR "leaking param: f"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200269 pf = f
270}
271
Russ Coxdb5f9da2011-08-28 12:05:00 -0400272func (f *Foo) foonoleak() { // ERROR "f does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200273 F.x = f.x
274}
275
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200276func (f *Foo) Leak() { // ERROR "leaking param: f"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200277 f.fooleak()
278}
279
Russ Coxdb5f9da2011-08-28 12:05:00 -0400280func (f *Foo) NoLeak() { // ERROR "f does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200281 f.foonoleak()
282}
283
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200284func foo41(x int) { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400285 F.xx = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200286}
287
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200288func (f *Foo) foo42(x int) { // ERROR "f does not escape" "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400289 f.xx = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200290}
291
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200292func foo43(f *Foo, x int) { // ERROR "f does not escape" "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400293 f.xx = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200294}
295
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200296func foo44(yy *int) { // ERROR "leaking param: yy"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200297 F.xx = yy
298}
299
Russ Coxdb5f9da2011-08-28 12:05:00 -0400300func (f *Foo) foo45() { // ERROR "f does not escape"
301 F.x = f.x
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200302}
303
Rémy Oudompheng20c7e412013-03-15 09:03:45 +0100304// See foo13 above for explanation of why f leaks.
305func (f *Foo) foo46() { // ERROR "leaking param: f"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400306 F.xx = f.xx
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200307}
308
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200309func (f *Foo) foo47() { // ERROR "leaking param: f"
Russ Coxb4df33a2011-11-01 11:02:43 -0400310 f.xx = &f.x // ERROR "&f.x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200311}
312
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200313var ptrSlice []*int
314
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200315func foo50(i *int) { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200316 ptrSlice[0] = i
317}
318
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200319var ptrMap map[*int]*int
320
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200321func foo51(i *int) { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200322 ptrMap[i] = i
323}
324
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200325func indaddr1(x int) *int { // ERROR "moved to heap: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400326 return &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200327}
328
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200329func indaddr2(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400330 return *&x // ERROR "&x does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200331}
332
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200333func indaddr3(x *int32) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400334 return *(**int)(unsafe.Pointer(&x)) // ERROR "&x does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200335}
336
337// From package math:
338
339func Float32bits(f float32) uint32 {
Russ Coxb4df33a2011-11-01 11:02:43 -0400340 return *(*uint32)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200341}
342
343func Float32frombits(b uint32) float32 {
Russ Coxb4df33a2011-11-01 11:02:43 -0400344 return *(*float32)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200345}
346
347func Float64bits(f float64) uint64 {
Russ Coxb4df33a2011-11-01 11:02:43 -0400348 return *(*uint64)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200349}
350
351func Float64frombits(b uint64) float64 {
Russ Coxb4df33a2011-11-01 11:02:43 -0400352 return *(*float64)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200353}
354
355// contrast with
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200356func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f"
Russ Coxb4df33a2011-11-01 11:02:43 -0400357 return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200358}
359
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200360func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200361 return (*uint64)(unsafe.Pointer(f))
362}
363
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200364func typesw(i interface{}) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200365 switch val := i.(type) {
366 case *int:
367 return val
368 case *int8:
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200369 v := int(*val) // ERROR "moved to heap: v"
Russ Coxb4df33a2011-11-01 11:02:43 -0400370 return &v // ERROR "&v escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200371 }
372 return nil
373}
374
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200375func exprsw(i *int) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200376 switch j := i; *j + 110 {
377 case 12:
378 return j
379 case 42:
380 return nil
381 }
382 return nil
383
384}
385
386// assigning to an array element is like assigning to the array
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200387func foo60(i *int) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200388 var a [12]*int
389 a[0] = i
390 return a[1]
391}
392
Russ Coxdb5f9da2011-08-28 12:05:00 -0400393func foo60a(i *int) *int { // ERROR "i does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200394 var a [12]*int
395 a[0] = i
396 return nil
397}
398
399// assigning to a struct field is like assigning to the struct
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200400func foo61(i *int) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200401 type S struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400402 a, b *int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200403 }
404 var s S
405 s.a = i
406 return s.b
407}
408
Russ Coxdb5f9da2011-08-28 12:05:00 -0400409func foo61a(i *int) *int { // ERROR "i does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200410 type S struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400411 a, b *int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200412 }
413 var s S
414 s.a = i
415 return nil
416}
417
418// assigning to a struct field is like assigning to the struct but
419// here this subtlety is lost, since s.a counts as an assignment to a
420// track-losing dereference.
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200421func foo62(i *int) *int { // ERROR "leaking param: i"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200422 type S struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400423 a, b *int
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200424 }
Russ Coxdb5f9da2011-08-28 12:05:00 -0400425 s := new(S) // ERROR "new[(]S[)] does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200426 s.a = i
Russ Coxdb5f9da2011-08-28 12:05:00 -0400427 return nil // s.b
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200428}
429
Russ Coxdb5f9da2011-08-28 12:05:00 -0400430type M interface {
431 M()
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200432}
433
Russ Coxdb5f9da2011-08-28 12:05:00 -0400434func foo63(m M) { // ERROR "m does not escape"
435}
436
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200437func foo64(m M) { // ERROR "leaking param: m"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200438 m.M()
439}
440
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200441func foo64b(m M) { // ERROR "leaking param: m"
Luuk van Dijkf2460a82011-09-07 19:03:11 +0200442 defer m.M()
443}
444
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200445type MV int
Russ Coxdb5f9da2011-08-28 12:05:00 -0400446
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200447func (MV) M() {}
448
449func foo65() {
450 var mv MV
Russ Coxb4df33a2011-11-01 11:02:43 -0400451 foo63(&mv) // ERROR "&mv does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200452}
453
454func foo66() {
Russ Coxb4df33a2011-11-01 11:02:43 -0400455 var mv MV // ERROR "moved to heap: mv"
456 foo64(&mv) // ERROR "&mv escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200457}
458
459func foo67() {
460 var mv MV
461 foo63(mv)
462}
463
464func foo68() {
465 var mv MV
Russ Coxdb5f9da2011-08-28 12:05:00 -0400466 foo64(mv) // escapes but it's an int so irrelevant
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200467}
468
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200469func foo69(m M) { // ERROR "leaking param: m"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200470 foo64(m)
471}
472
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200473func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200474 m = mv1
475 foo64(m)
476}
477
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200478func foo71(x *int) []*int { // ERROR "leaking param: x"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200479 var y []*int
480 y = append(y, x)
481 return y
482}
483
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200484func foo71a(x int) []*int { // ERROR "moved to heap: x"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200485 var y []*int
Russ Coxb4df33a2011-11-01 11:02:43 -0400486 y = append(y, &x) // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200487 return y
488}
489
490func foo72() {
491 var x int
492 var y [1]*int
Russ Coxb4df33a2011-11-01 11:02:43 -0400493 y[0] = &x // ERROR "&x does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200494}
495
496func foo72aa() [10]*int {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200497 var x int // ERROR "moved to heap: x"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200498 var y [10]*int
Russ Coxb4df33a2011-11-01 11:02:43 -0400499 y[0] = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200500 return y
501}
502
503func foo72a() {
504 var y [10]*int
505 for i := 0; i < 10; i++ {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400506 // escapes its scope
Russ Coxb4df33a2011-11-01 11:02:43 -0400507 x := i // ERROR "moved to heap: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400508 y[i] = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200509 }
510 return
511}
512
513func foo72b() [10]*int {
514 var y [10]*int
515 for i := 0; i < 10; i++ {
Russ Coxb4df33a2011-11-01 11:02:43 -0400516 x := i // ERROR "moved to heap: x"
517 y[i] = &x // ERROR "&x escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200518 }
519 return y
520}
521
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200522// issue 2145
523func foo73() {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200524 s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200525 for _, v := range s {
Russ Coxb4df33a2011-11-01 11:02:43 -0400526 vv := v // ERROR "moved to heap: vv"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400527 // actually just escapes its scope
528 defer func() { // ERROR "func literal escapes to heap"
Russ Coxb4df33a2011-11-01 11:02:43 -0400529 println(vv) // ERROR "&vv escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200530 }()
531 }
532}
533
534func foo74() {
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200535 s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200536 for _, v := range s {
Russ Coxb4df33a2011-11-01 11:02:43 -0400537 vv := v // ERROR "moved to heap: vv"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400538 // actually just escapes its scope
539 fn := func() { // ERROR "func literal escapes to heap"
Russ Coxb4df33a2011-11-01 11:02:43 -0400540 println(vv) // ERROR "&vv escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200541 }
542 defer fn()
543 }
544}
545
Rémy Oudomphengba97d522012-08-31 22:23:37 +0200546// issue 3975
547func foo74b() {
548 var array [3]func()
549 s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
550 for i, v := range s {
551 vv := v // ERROR "moved to heap: vv"
552 // actually just escapes its scope
553 array[i] = func() { // ERROR "func literal escapes to heap"
554 println(vv) // ERROR "&vv escapes to heap"
555 }
556 }
557}
558
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200559func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200560 return y
561}
562
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200563func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400564 return &x[0] // ERROR "&x.0. escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200565}
566
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100567func foo75(z *int) { // ERROR "z does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400568 myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200569}
570
Russ Coxdb5f9da2011-08-28 12:05:00 -0400571func foo75a(z *int) { // ERROR "z does not escape"
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100572 myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
573}
574
575func foo75esc(z *int) { // ERROR "leaking param: z"
576 gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
577}
578
579func foo75aesc(z *int) { // ERROR "z does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +0100580 var ppi **interface{} // assignments to pointer dereferences lose track
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100581 *ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200582}
583
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200584func foo76(z *int) { // ERROR "leaking param: z"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400585 myprint(nil, z) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200586}
587
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200588func foo76a(z *int) { // ERROR "leaking param: z"
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100589 myprint1(nil, z) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200590}
591
592func foo76b() {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400593 myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200594}
595
596func foo76c() {
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100597 myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200598}
599
600func foo76d() {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400601 defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200602}
603
604func foo76e() {
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100605 defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200606}
607
608func foo76f() {
609 for {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400610 // TODO: This one really only escapes its scope, but we don't distinguish yet.
611 defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200612 }
613}
614
615func foo76g() {
616 for {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400617 defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200618 }
619}
620
Russ Coxdb5f9da2011-08-28 12:05:00 -0400621func foo77(z []interface{}) { // ERROR "z does not escape"
622 myprint(nil, z...) // z does not escape
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200623}
624
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100625func foo77a(z []interface{}) { // ERROR "z does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200626 myprint1(nil, z...)
627}
628
Luuk van Dijk507fcf32012-10-29 13:38:21 +0100629func foo77b(z []interface{}) { // ERROR "leaking param: z"
630 var ppi **interface{}
631 *ppi = myprint1(nil, z...)
632}
633
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200634func foo78(z int) *int { // ERROR "moved to heap: z"
Russ Coxb4df33a2011-11-01 11:02:43 -0400635 return &z // ERROR "&z escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200636}
637
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200638func foo78a(z int) *int { // ERROR "moved to heap: z"
Russ Coxb4df33a2011-11-01 11:02:43 -0400639 y := &z // ERROR "&z escapes to heap"
640 x := &y // ERROR "&y does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400641 return *x // really return y
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200642}
643
644func foo79() *int {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400645 return new(int) // ERROR "new[(]int[)] escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200646}
647
648func foo80() *int {
649 var z *int
650 for {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400651 // Really just escapes its scope but we don't distinguish
652 z = new(int) // ERROR "new[(]int[)] escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200653 }
654 _ = z
655 return nil
656}
657
658func foo81() *int {
659 for {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400660 z := new(int) // ERROR "new[(]int[)] does not escape"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200661 _ = z
662 }
663 return nil
664}
665
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +0100666func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param"
667
668func noop(x, y *int) {} // ERROR "does not escape"
669
670func foo82() {
671 var x, y, z int // ERROR "moved to heap"
672 go noop(tee(&z)) // ERROR "&z escapes to heap"
673 go noop(&x, &y) // ERROR "escapes to heap"
674 for {
675 var u, v, w int // ERROR "moved to heap"
676 defer noop(tee(&u)) // ERROR "&u escapes to heap"
677 defer noop(&v, &w) // ERROR "escapes to heap"
678 }
679}
680
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200681type Fooer interface {
682 Foo()
683}
684
685type LimitedFooer struct {
Russ Coxdb5f9da2011-08-28 12:05:00 -0400686 Fooer
687 N int64
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200688}
689
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200690func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r"
691 return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200692}
693
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200694func foo90(x *int) map[*int]*int { // ERROR "leaking param: x"
Russ Cox434a6c82011-12-02 14:45:07 -0500695 return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200696}
697
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200698func foo91(x *int) map[*int]*int { // ERROR "leaking param: x"
Russ Cox434a6c82011-12-02 14:45:07 -0500699 return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap"
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200700}
701
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200702func foo92(x *int) [2]*int { // ERROR "leaking param: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400703 return [2]*int{x, nil}
Luuk van Dijk847b61b2011-08-24 19:07:08 +0200704}
705
Russ Cox0227c452011-08-25 09:26:13 -0400706// does not leak c
Russ Coxdb5f9da2011-08-28 12:05:00 -0400707func foo93(c chan *int) *int { // ERROR "c does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400708 for v := range c {
709 return v
710 }
711 return nil
712}
713
714// does not leak m
Russ Coxdb5f9da2011-08-28 12:05:00 -0400715func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400716 for k, v := range m {
717 if b {
718 return k
719 }
720 return v
721 }
722 return nil
723}
724
725// does leak x
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200726func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape" "leaking param: x"
Russ Cox0227c452011-08-25 09:26:13 -0400727 m[x] = x
728}
729
730// does not leak m
Russ Coxdb5f9da2011-08-28 12:05:00 -0400731func foo96(m []*int) *int { // ERROR "m does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400732 return m[0]
733}
734
735// does leak m
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200736func foo97(m [1]*int) *int { // ERROR "leaking param: m"
Russ Cox0227c452011-08-25 09:26:13 -0400737 return m[0]
738}
739
740// does not leak m
Russ Coxdb5f9da2011-08-28 12:05:00 -0400741func foo98(m map[int]*int) *int { // ERROR "m does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400742 return m[0]
743}
744
745// does leak m
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200746func foo99(m *[1]*int) []*int { // ERROR "leaking param: m"
Russ Cox0227c452011-08-25 09:26:13 -0400747 return m[:]
748}
749
750// does not leak m
Russ Coxdb5f9da2011-08-28 12:05:00 -0400751func foo100(m []*int) *int { // ERROR "m does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400752 for _, v := range m {
753 return v
754 }
755 return nil
756}
757
758// does leak m
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200759func foo101(m [1]*int) *int { // ERROR "leaking param: m"
Russ Cox0227c452011-08-25 09:26:13 -0400760 for _, v := range m {
761 return v
762 }
763 return nil
764}
765
Russ Coxdb5f9da2011-08-28 12:05:00 -0400766// does not leak m
767func foo101a(m [1]*int) *int { // ERROR "m does not escape"
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200768 for i := range m { // ERROR "moved to heap: i"
Russ Coxb4df33a2011-11-01 11:02:43 -0400769 return &i // ERROR "&i escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400770 }
771 return nil
772}
773
Russ Cox0227c452011-08-25 09:26:13 -0400774// does leak x
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200775func foo102(m []*int, x *int) { // ERROR "m does not escape" "leaking param: x"
Russ Cox0227c452011-08-25 09:26:13 -0400776 m[0] = x
777}
778
779// does not leak x
Russ Coxdb5f9da2011-08-28 12:05:00 -0400780func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400781 m[0] = x
782}
783
784var y []*int
785
786// does not leak x
Russ Coxb4df33a2011-11-01 11:02:43 -0400787func foo104(x []*int) { // ERROR "x does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400788 copy(y, x)
789}
790
791// does not leak x
Russ Coxb4df33a2011-11-01 11:02:43 -0400792func foo105(x []*int) { // ERROR "x does not escape"
Russ Cox0227c452011-08-25 09:26:13 -0400793 _ = append(y, x...)
794}
795
796// does leak x
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200797func foo106(x *int) { // ERROR "leaking param: x"
Russ Cox0227c452011-08-25 09:26:13 -0400798 _ = append(y, x)
799}
Russ Coxdb5f9da2011-08-28 12:05:00 -0400800
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200801func foo107(x *int) map[*int]*int { // ERROR "leaking param: x"
802 return map[*int]*int{x: nil} // ERROR "map.* literal escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400803}
804
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200805func foo108(x *int) map[*int]*int { // ERROR "leaking param: x"
806 return map[*int]*int{nil: x} // ERROR "map.* literal escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400807}
808
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200809func foo109(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400810 m := map[*int]*int{x: nil} // ERROR "map.* literal does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400811 for k, _ := range m {
812 return k
813 }
814 return nil
815}
816
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200817func foo110(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400818 m := map[*int]*int{nil: x} // ERROR "map.* literal does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400819 return m[nil]
820}
821
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200822func foo111(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400823 m := []*int{x} // ERROR "\[\]\*int literal does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400824 return m[0]
825}
826
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200827func foo112(x *int) *int { // ERROR "leaking param: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400828 m := [1]*int{x}
829 return m[0]
830}
831
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200832func foo113(x *int) *int { // ERROR "leaking param: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400833 m := Bar{ii: x}
834 return m.ii
835}
836
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200837func foo114(x *int) *int { // ERROR "leaking param: x"
Russ Coxb4df33a2011-11-01 11:02:43 -0400838 m := &Bar{ii: x} // ERROR "&Bar literal does not escape"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400839 return m.ii
840}
841
Luuk van Dijkb536adb2011-10-08 19:37:06 +0200842func foo115(x *int) *int { // ERROR "leaking param: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400843 return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
844}
845
846func foo116(b bool) *int {
847 if b {
Russ Coxb4df33a2011-11-01 11:02:43 -0400848 x := 1 // ERROR "moved to heap: x"
849 return &x // ERROR "&x escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400850 } else {
Russ Coxb4df33a2011-11-01 11:02:43 -0400851 y := 1 // ERROR "moved to heap: y"
852 return &y // ERROR "&y escapes to heap"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400853 }
854 return nil
855}
856
Russ Coxb4df33a2011-11-01 11:02:43 -0400857func foo117(unknown func(interface{})) { // ERROR "unknown does not escape"
858 x := 1 // ERROR "moved to heap: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400859 unknown(&x) // ERROR "&x escapes to heap"
860}
861
Russ Coxb4df33a2011-11-01 11:02:43 -0400862func foo118(unknown func(*int)) { // ERROR "unknown does not escape"
863 x := 1 // ERROR "moved to heap: x"
Russ Coxdb5f9da2011-08-28 12:05:00 -0400864 unknown(&x) // ERROR "&x escapes to heap"
865}
Russ Cox77f0bdc2011-08-28 23:29:34 -0400866
867func external(*int)
868
Russ Coxb4df33a2011-11-01 11:02:43 -0400869func foo119(x *int) { // ERROR "leaking param: x"
Russ Cox77f0bdc2011-08-28 23:29:34 -0400870 external(x)
871}
Russ Cox60d47102011-09-01 13:44:46 -0400872
873func foo120() {
874 // formerly exponential time analysis
875L1:
876L2:
877L3:
878L4:
879L5:
880L6:
881L7:
882L8:
883L9:
884L10:
885L11:
886L12:
887L13:
888L14:
889L15:
890L16:
891L17:
892L18:
893L19:
894L20:
895L21:
896L22:
897L23:
898L24:
899L25:
900L26:
901L27:
902L28:
903L29:
904L30:
905L31:
906L32:
907L33:
908L34:
909L35:
910L36:
911L37:
912L38:
913L39:
914L40:
915L41:
916L42:
917L43:
918L44:
919L45:
920L46:
921L47:
922L48:
923L49:
924L50:
925L51:
926L52:
927L53:
928L54:
929L55:
930L56:
931L57:
932L58:
933L59:
934L60:
935L61:
936L62:
937L63:
938L64:
939L65:
940L66:
941L67:
942L68:
943L69:
944L70:
945L71:
946L72:
947L73:
948L74:
949L75:
950L76:
951L77:
952L78:
953L79:
954L80:
955L81:
956L82:
957L83:
958L84:
959L85:
960L86:
961L87:
962L88:
963L89:
964L90:
965L91:
966L92:
967L93:
968L94:
969L95:
970L96:
971L97:
972L98:
973L99:
974L100:
975 // use the labels to silence compiler errors
976 goto L1
977 goto L2
978 goto L3
979 goto L4
980 goto L5
981 goto L6
982 goto L7
983 goto L8
984 goto L9
985 goto L10
986 goto L11
987 goto L12
988 goto L13
989 goto L14
990 goto L15
991 goto L16
992 goto L17
993 goto L18
994 goto L19
995 goto L20
996 goto L21
997 goto L22
998 goto L23
999 goto L24
1000 goto L25
1001 goto L26
1002 goto L27
1003 goto L28
1004 goto L29
1005 goto L30
1006 goto L31
1007 goto L32
1008 goto L33
1009 goto L34
1010 goto L35
1011 goto L36
1012 goto L37
1013 goto L38
1014 goto L39
1015 goto L40
1016 goto L41
1017 goto L42
1018 goto L43
1019 goto L44
1020 goto L45
1021 goto L46
1022 goto L47
1023 goto L48
1024 goto L49
1025 goto L50
1026 goto L51
1027 goto L52
1028 goto L53
1029 goto L54
1030 goto L55
1031 goto L56
1032 goto L57
1033 goto L58
1034 goto L59
1035 goto L60
1036 goto L61
1037 goto L62
1038 goto L63
1039 goto L64
1040 goto L65
1041 goto L66
1042 goto L67
1043 goto L68
1044 goto L69
1045 goto L70
1046 goto L71
1047 goto L72
1048 goto L73
1049 goto L74
1050 goto L75
1051 goto L76
1052 goto L77
1053 goto L78
1054 goto L79
1055 goto L80
1056 goto L81
1057 goto L82
1058 goto L83
1059 goto L84
1060 goto L85
1061 goto L86
1062 goto L87
1063 goto L88
1064 goto L89
1065 goto L90
1066 goto L91
1067 goto L92
1068 goto L93
1069 goto L94
1070 goto L95
1071 goto L96
1072 goto L97
1073 goto L98
1074 goto L99
1075 goto L100
1076}
Russ Coxb4df33a2011-11-01 11:02:43 -04001077
1078func foo121() {
1079 for i := 0; i < 10; i++ {
1080 defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
1081 go myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
1082 }
1083}
1084
1085// same as foo121 but check across import
1086func foo121b() {
1087 for i := 0; i < 10; i++ {
1088 defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
1089 go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
1090 }
1091}
Luuk van Dijk9bf34782011-12-15 17:35:59 +01001092
1093// a harmless forward jump
1094func foo122() {
1095 var i *int
1096
1097 goto L1
1098L1:
Luuk van Dijk55830602012-04-23 15:39:01 -04001099 i = new(int) // ERROR "new.int. does not escape"
Luuk van Dijk9bf34782011-12-15 17:35:59 +01001100 _ = i
1101}
1102
1103// a backward jump, increases loopdepth
1104func foo123() {
1105 var i *int
1106
1107L1:
Luuk van Dijk55830602012-04-23 15:39:01 -04001108 i = new(int) // ERROR "new.int. escapes to heap"
Luuk van Dijk9bf34782011-12-15 17:35:59 +01001109
1110 goto L1
1111 _ = i
Rémy Oudompheng94ff3112012-01-12 12:08:40 +01001112}
Luuk van Dijk55830602012-04-23 15:39:01 -04001113
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001114func foo124(x **int) { // ERROR "x does not escape"
1115 var i int // ERROR "moved to heap: i"
1116 p := &i // ERROR "&i escapes"
1117 func() { // ERROR "func literal does not escape"
1118 *x = p // ERROR "leaking closure reference p"
Luuk van Dijk55830602012-04-23 15:39:01 -04001119 }()
1120}
1121
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001122func foo125(ch chan *int) { // ERROR "does not escape"
1123 var i int // ERROR "moved to heap"
1124 p := &i // ERROR "&i escapes to heap"
1125 func() { // ERROR "func literal does not escape"
1126 ch <- p // ERROR "leaking closure reference p"
Luuk van Dijk55830602012-04-23 15:39:01 -04001127 }()
1128}
1129
1130func foo126() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001131 var px *int // loopdepth 0
Luuk van Dijk55830602012-04-23 15:39:01 -04001132 for {
1133 // loopdepth 1
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001134 var i int // ERROR "moved to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001135 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001136 px = &i // ERROR "&i escapes"
Luuk van Dijk55830602012-04-23 15:39:01 -04001137 }()
1138 }
Robert Griesemer99d87722013-09-17 15:24:54 -07001139 _ = px
Luuk van Dijk55830602012-04-23 15:39:01 -04001140}
1141
1142var px *int
1143
1144func foo127() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001145 var i int // ERROR "moved to heap: i"
1146 p := &i // ERROR "&i escapes to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001147 q := p
1148 px = q
1149}
1150
1151func foo128() {
1152 var i int
1153 p := &i // ERROR "&i does not escape"
1154 q := p
1155 _ = q
1156}
1157
1158func foo129() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001159 var i int // ERROR "moved to heap: i"
1160 p := &i // ERROR "&i escapes to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001161 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001162 q := p // ERROR "leaking closure reference p"
1163 func() { // ERROR "func literal does not escape"
1164 r := q // ERROR "leaking closure reference q"
Luuk van Dijk55830602012-04-23 15:39:01 -04001165 px = r
1166 }()
1167 }()
1168}
1169
1170func foo130() {
1171 for {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001172 var i int // ERROR "moved to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001173 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001174 px = &i // ERROR "&i escapes" "leaking closure reference i"
Luuk van Dijk55830602012-04-23 15:39:01 -04001175 }()
1176 }
1177}
1178
1179func foo131() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001180 var i int // ERROR "moved to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001181 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001182 px = &i // ERROR "&i escapes" "leaking closure reference i"
Luuk van Dijk55830602012-04-23 15:39:01 -04001183 }()
1184}
1185
1186func foo132() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001187 var i int // ERROR "moved to heap"
1188 go func() { // ERROR "func literal escapes to heap"
1189 px = &i // ERROR "&i escapes" "leaking closure reference i"
Luuk van Dijk55830602012-04-23 15:39:01 -04001190 }()
1191}
1192
1193func foo133() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001194 var i int // ERROR "moved to heap"
1195 defer func() { // ERROR "func literal does not escape"
1196 px = &i // ERROR "&i escapes" "leaking closure reference i"
Luuk van Dijk55830602012-04-23 15:39:01 -04001197 }()
1198}
1199
1200func foo134() {
1201 var i int
1202 p := &i // ERROR "&i does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001203 func() { // ERROR "func literal does not escape"
Luuk van Dijk55830602012-04-23 15:39:01 -04001204 q := p
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 r := q
1207 _ = r
1208 }()
1209 }()
1210}
1211
1212func foo135() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001213 var i int // ERROR "moved to heap: i"
1214 p := &i // ERROR "&i escapes to heap" "moved to heap: p"
1215 go func() { // ERROR "func literal escapes to heap"
1216 q := p // ERROR "&p escapes to heap"
1217 func() { // ERROR "func literal does not escape"
Luuk van Dijk55830602012-04-23 15:39:01 -04001218 r := q
1219 _ = r
1220 }()
1221 }()
1222}
1223
1224func foo136() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001225 var i int // ERROR "moved to heap: i"
1226 p := &i // ERROR "&i escapes to heap" "moved to heap: p"
1227 go func() { // ERROR "func literal escapes to heap"
1228 q := p // ERROR "&p escapes to heap" "leaking closure reference p"
1229 func() { // ERROR "func literal does not escape"
Luuk van Dijk55830602012-04-23 15:39:01 -04001230 r := q // ERROR "leaking closure reference q"
1231 px = r
1232 }()
1233 }()
1234}
1235
1236func foo137() {
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001237 var i int // ERROR "moved to heap: i"
1238 p := &i // ERROR "&i escapes to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001239 func() { // ERROR "func literal does not escape"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001240 q := p // ERROR "leaking closure reference p" "moved to heap: q"
Luuk van Dijk55830602012-04-23 15:39:01 -04001241 go func() { // ERROR "func literal escapes to heap"
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001242 r := q // ERROR "&q escapes to heap"
Luuk van Dijk55830602012-04-23 15:39:01 -04001243 _ = r
1244 }()
1245 }()
1246}
Russ Cox54af7522012-09-24 15:53:12 -04001247
1248func foo138() *byte {
1249 type T struct {
1250 x [1]byte
1251 }
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001252 t := new(T) // ERROR "new.T. escapes to heap"
Russ Cox54af7522012-09-24 15:53:12 -04001253 return &t.x[0] // ERROR "&t.x.0. escapes to heap"
1254}
1255
1256func foo139() *byte {
1257 type T struct {
1258 x struct {
1259 y byte
1260 }
1261 }
Rémy Oudompheng1dcf6582012-12-20 23:27:28 +01001262 t := new(T) // ERROR "new.T. escapes to heap"
Russ Cox54af7522012-09-24 15:53:12 -04001263 return &t.x.y // ERROR "&t.x.y escapes to heap"
1264}
Russ Cox572d9842013-02-04 22:48:31 -05001265
1266// issue 4751
1267func foo140() interface{} {
1268 type T struct {
1269 X string
1270 }
1271 type U struct {
1272 X string
1273 T *T
1274 }
1275 t := &T{} // ERROR "&T literal escapes to heap"
1276 return U{
1277 X: t.X,
1278 T: t,
1279 }
1280}
Russ Coxfd178d62013-02-05 07:00:38 -05001281
1282//go:noescape
1283
1284func F1([]byte)
1285
1286func F2([]byte)
1287
1288//go:noescape
1289
1290func F3(x []byte) // ERROR "F3 x does not escape"
1291
1292func F4(x []byte)
1293
1294func G() {
1295 var buf1 [10]byte
1296 F1(buf1[:]) // ERROR "buf1 does not escape"
1297
1298 var buf2 [10]byte // ERROR "moved to heap: buf2"
1299 F2(buf2[:]) // ERROR "buf2 escapes to heap"
1300
1301 var buf3 [10]byte
1302 F3(buf3[:]) // ERROR "buf3 does not escape"
1303
1304 var buf4 [10]byte // ERROR "moved to heap: buf4"
1305 F4(buf4[:]) // ERROR "buf4 escapes to heap"
1306}
Russ Cox38e9b072013-03-20 23:53:27 -04001307
1308type Tm struct {
1309 x int
1310}
1311
1312func (t *Tm) M() { // ERROR "t does not escape"
1313}
1314
1315func foo141() {
1316 var f func()
1317
1318 t := new(Tm) // ERROR "escapes to heap"
1319 f = t.M // ERROR "t.M does not escape"
1320 _ = f
1321}
1322
1323var gf func()
1324
1325func foo142() {
1326 t := new(Tm) // ERROR "escapes to heap"
1327 gf = t.M // ERROR "t.M escapes to heap"
1328}
Rémy Oudompheng35773982013-05-22 22:45:38 +02001329
1330// issue 3888.
1331func foo143() {
1332 for i := 0; i < 1000; i++ {
1333 func() { // ERROR "func literal does not escape"
1334 for i := 0; i < 1; i++ {
1335 var t Tm
1336 t.M() // ERROR "t does not escape"
1337 }
1338 }()
1339 }
1340}
Russ Cox148fac72013-06-25 17:28:49 -04001341
1342// issue 5773
1343// Check that annotations take effect regardless of whether they
1344// are before or after the use in the source code.
1345
1346//go:noescape
1347
1348func foo144a(*int)
1349
1350func foo144() {
1351 var x int
1352 foo144a(&x) // ERROR "&x does not escape"
1353 var y int
1354 foo144b(&y) // ERROR "&y does not escape"
1355}
1356
1357//go:noescape
1358
1359func foo144b(*int)