blob: 2c43b96ba03163e3359a8574cf146b0d0afc82b8 [file] [log] [blame]
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +03001// errorcheck -0 -m -l
2
Emmanuel Odeke53fd5222016-04-10 14:32:26 -07003// Copyright 2015 The Go Authors. All rights reserved.
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +03004// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test escape analysis for function parameters.
8
9// In this test almost everything is BAD except the simplest cases
10// where input directly flows to output.
11
12package escape
13
14var sink interface{}
15
16// in -> out
David Chase7fbb1b32015-03-26 16:36:15 -040017func param0(p *int) *int { // ERROR "leaking param: p to result ~r1"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +030018 return p
19}
20
21func caller0a() {
22 i := 0
23 _ = param0(&i) // ERROR "caller0a &i does not escape$"
24}
25
26func caller0b() {
27 i := 0 // ERROR "moved to heap: i$"
28 sink = param0(&i) // ERROR "&i escapes to heap$" "param0\(&i\) escapes to heap"
29}
30
31// in, in -> out, out
David Chase7fbb1b32015-03-26 16:36:15 -040032func param1(p1, p2 *int) (*int, *int) { // ERROR "leaking param: p1 to result ~r2" "leaking param: p2 to result ~r3"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +030033 return p1, p2
34}
35
36func caller1() {
37 i := 0 // ERROR "moved to heap: i$"
38 j := 0
39 sink, _ = param1(&i, &j) // ERROR "&i escapes to heap$" "caller1 &j does not escape$"
40}
41
42// in -> other in
43func param2(p1 *int, p2 **int) { // ERROR "leaking param: p1$" "param2 p2 does not escape$"
44 *p2 = p1
45}
46
47func caller2a() {
48 i := 0 // ERROR "moved to heap: i$"
49 var p *int
50 param2(&i, &p) // ERROR "&i escapes to heap$" "caller2a &p does not escape$"
51 _ = p
52}
53
54func caller2b() {
55 i := 0 // ERROR "moved to heap: i$"
56 var p *int
57 param2(&i, &p) // ERROR "&i escapes to heap$" "caller2b &p does not escape$"
58 sink = p // ERROR "p escapes to heap$"
59}
60
61// in -> in
62type Pair struct {
63 p1 *int
64 p2 *int
65}
66
David Chase7fbb1b32015-03-26 16:36:15 -040067func param3(p *Pair) { // ERROR "leaking param content: p$"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +030068 p.p1 = p.p2
69}
70
71func caller3a() {
72 i := 0 // ERROR "moved to heap: i$"
73 j := 0 // ERROR "moved to heap: j$"
David Chase7fbb1b32015-03-26 16:36:15 -040074 p := Pair{&i, &j} // ERROR "&i escapes to heap$" "&j escapes to heap$"
75 param3(&p) // ERROR "caller3a &p does not escape"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +030076 _ = p
77}
78
79func caller3b() {
80 i := 0 // ERROR "moved to heap: i$"
81 j := 0 // ERROR "moved to heap: j$"
David Chase7fbb1b32015-03-26 16:36:15 -040082 p := Pair{&i, &j} // ERROR "&i escapes to heap$" "&j escapes to heap$"
83 param3(&p) // ERROR "caller3b &p does not escape"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +030084 sink = p // ERROR "p escapes to heap$"
85}
86
87// in -> rcvr
88func (p *Pair) param4(i *int) { // ERROR "\(\*Pair\).param4 p does not escape$" "leaking param: i$"
89 p.p1 = i
90}
91
92func caller4a() {
93 i := 0 // ERROR "moved to heap: i$"
94 p := Pair{}
95 p.param4(&i) // ERROR "&i escapes to heap$" "caller4a p does not escape$"
96 _ = p
97}
98
99func caller4b() {
100 i := 0 // ERROR "moved to heap: i$"
101 p := Pair{}
102 p.param4(&i) // ERROR "&i escapes to heap$" "caller4b p does not escape$"
103 sink = p // ERROR "p escapes to heap$"
104}
105
106// in -> heap
107func param5(i *int) { // ERROR "leaking param: i$"
108 sink = i // ERROR "i escapes to heap$"
109}
110
111func caller5() {
112 i := 0 // ERROR "moved to heap: i$"
113 param5(&i) // ERROR "&i escapes to heap$"
114}
115
116// *in -> heap
David Chase7fbb1b32015-03-26 16:36:15 -0400117func param6(i ***int) { // ERROR "leaking param content: i$"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300118 sink = *i // ERROR "\*i escapes to heap$"
119}
120
121func caller6a() {
122 i := 0 // ERROR "moved to heap: i$"
123 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
David Chase7fbb1b32015-03-26 16:36:15 -0400124 p2 := &p // ERROR "&p escapes to heap$"
125 param6(&p2) // ERROR "caller6a &p2 does not escape"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300126}
127
128// **in -> heap
David Chase7fbb1b32015-03-26 16:36:15 -0400129func param7(i ***int) { // ERROR "leaking param content: i$"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300130 sink = **i // ERROR "\* \(\*i\) escapes to heap"
131}
132
133func caller7() {
134 i := 0 // ERROR "moved to heap: i$"
135 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
David Chase7fbb1b32015-03-26 16:36:15 -0400136 p2 := &p // ERROR "&p escapes to heap$"
137 param7(&p2) // ERROR "caller7 &p2 does not escape"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300138}
139
140// **in -> heap
141func param8(i **int) { // ERROR "param8 i does not escape$"
142 sink = **i // ERROR "\* \(\*i\) escapes to heap"
143}
144
145func caller8() {
146 i := 0
147 p := &i // ERROR "caller8 &i does not escape$"
148 param8(&p) // ERROR "caller8 &p does not escape$"
149}
150
151// *in -> out
David Chase7fbb1b32015-03-26 16:36:15 -0400152func param9(p ***int) **int { // ERROR "leaking param: p to result ~r1 level=1"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300153 return *p
154}
155
156func caller9a() {
David Chase7fbb1b32015-03-26 16:36:15 -0400157 i := 0
158 p := &i // ERROR "caller9a &i does not escape"
159 p2 := &p // ERROR "caller9a &p does not escape"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300160 _ = param9(&p2) // ERROR "caller9a &p2 does not escape$"
161}
162
163func caller9b() {
164 i := 0 // ERROR "moved to heap: i$"
165 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
166 p2 := &p // ERROR "&p escapes to heap$"
167 sink = param9(&p2) // ERROR "caller9b &p2 does not escape$" "param9\(&p2\) escapes to heap"
168}
169
170// **in -> out
David Chase7fbb1b32015-03-26 16:36:15 -0400171func param10(p ***int) *int { // ERROR "leaking param: p to result ~r1 level=2"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300172 return **p
173}
174
175func caller10a() {
David Chase7fbb1b32015-03-26 16:36:15 -0400176 i := 0
177 p := &i // ERROR "caller10a &i does not escape"
178 p2 := &p // ERROR "caller10a &p does not escape"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300179 _ = param10(&p2) // ERROR "caller10a &p2 does not escape$"
180}
181
182func caller10b() {
183 i := 0 // ERROR "moved to heap: i$"
David Chase7fbb1b32015-03-26 16:36:15 -0400184 p := &i // ERROR "&i escapes to heap$"
185 p2 := &p // ERROR "caller10b &p does not escape$"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300186 sink = param10(&p2) // ERROR "caller10b &p2 does not escape$" "param10\(&p2\) escapes to heap"
187}
188
David Chase7fbb1b32015-03-26 16:36:15 -0400189// in escapes to heap (address of param taken and returned)
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300190func param11(i **int) ***int { // ERROR "moved to heap: i$"
191 return &i // ERROR "&i escapes to heap$"
192}
193
194func caller11a() {
David Chase7fbb1b32015-03-26 16:36:15 -0400195 i := 0 // ERROR "moved to heap: i"
196 p := &i // ERROR "moved to heap: p" "&i escapes to heap"
197 _ = param11(&p) // ERROR "&p escapes to heap"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300198}
199
200func caller11b() {
201 i := 0 // ERROR "moved to heap: i$"
202 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
203 sink = param11(&p) // ERROR "&p escapes to heap$" "param11\(&p\) escapes to heap"
204}
205
David Chase7fbb1b32015-03-26 16:36:15 -0400206func caller11c() { // GOOD
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300207 i := 0 // ERROR "moved to heap: i$"
David Chase7fbb1b32015-03-26 16:36:15 -0400208 p := &i // ERROR "moved to heap: p" "&i escapes to heap"
209 sink = *param11(&p) // ERROR "&p escapes to heap" "\*param11\(&p\) escapes to heap"
210}
211
212func caller11d() {
213 i := 0 // ERROR "moved to heap: i$"
214 p := &i // ERROR "&i escapes to heap" "moved to heap: p"
215 p2 := &p // ERROR "&p escapes to heap"
216 sink = param11(p2) // ERROR "param11\(p2\) escapes to heap"
Dmitry Vyukovd593f4a2015-02-19 19:10:31 +0300217}
218
219// &in -> rcvr
220type Indir struct {
221 p ***int
222}
223
224func (r *Indir) param12(i **int) { // ERROR "\(\*Indir\).param12 r does not escape$" "moved to heap: i$"
225 r.p = &i // ERROR "&i escapes to heap$"
226}
227
228func caller12a() {
229 i := 0 // ERROR "moved to heap: i$"
230 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
231 var r Indir
232 r.param12(&p) // ERROR "&p escapes to heap$" "caller12a r does not escape$"
233 _ = r
234}
235
236func caller12b() {
237 i := 0 // ERROR "moved to heap: i$"
238 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
239 r := &Indir{} // ERROR "caller12b &Indir literal does not escape$"
240 r.param12(&p) // ERROR "&p escapes to heap$"
241 _ = r
242}
243
244func caller12c() {
245 i := 0 // ERROR "moved to heap: i$"
246 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
247 r := Indir{}
248 r.param12(&p) // ERROR "&p escapes to heap$" "caller12c r does not escape$"
249 sink = r // ERROR "r escapes to heap$"
250}
251
252func caller12d() {
253 i := 0 // ERROR "moved to heap: i$"
254 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
255 r := Indir{}
256 r.param12(&p) // ERROR "&p escapes to heap$" "caller12d r does not escape$"
257 sink = **r.p // ERROR "\* \(\*r\.p\) escapes to heap"
258}
259
260// in -> value rcvr
261type Val struct {
262 p **int
263}
264
265func (v Val) param13(i *int) { // ERROR "Val.param13 v does not escape$" "leaking param: i$"
266 *v.p = i
267}
268
269func caller13a() {
270 i := 0 // ERROR "moved to heap: i$"
271 var p *int
272 var v Val
273 v.p = &p // ERROR "caller13a &p does not escape$"
274 v.param13(&i) // ERROR "&i escapes to heap$"
275 _ = v
276}
277
278func caller13b() {
279 i := 0 // ERROR "moved to heap: i$"
280 var p *int
281 v := Val{&p} // ERROR "caller13b &p does not escape$"
282 v.param13(&i) // ERROR "&i escapes to heap$"
283 _ = v
284}
285
286func caller13c() {
287 i := 0 // ERROR "moved to heap: i$"
288 var p *int
289 v := &Val{&p} // ERROR "caller13c &Val literal does not escape$" "caller13c &p does not escape$"
290 v.param13(&i) // ERROR "&i escapes to heap$"
291 _ = v
292}
293
294func caller13d() {
295 i := 0 // ERROR "moved to heap: i$"
296 var p *int // ERROR "moved to heap: p$"
297 var v Val
298 v.p = &p // ERROR "&p escapes to heap$"
299 v.param13(&i) // ERROR "&i escapes to heap$"
300 sink = v // ERROR "v escapes to heap$"
301}
302
303func caller13e() {
304 i := 0 // ERROR "moved to heap: i$"
305 var p *int // ERROR "moved to heap: p$"
306 v := Val{&p} // ERROR "&p escapes to heap$"
307 v.param13(&i) // ERROR "&i escapes to heap$"
308 sink = v // ERROR "v escapes to heap$"
309}
310
311func caller13f() {
312 i := 0 // ERROR "moved to heap: i$"
313 var p *int // ERROR "moved to heap: p$"
314 v := &Val{&p} // ERROR "&Val literal escapes to heap$" "&p escapes to heap$"
315 v.param13(&i) // ERROR "&i escapes to heap$"
316 sink = v // ERROR "v escapes to heap$"
317}
318
319func caller13g() {
320 i := 0 // ERROR "moved to heap: i$"
321 var p *int
322 v := Val{&p} // ERROR "caller13g &p does not escape$"
323 v.param13(&i) // ERROR "&i escapes to heap$"
324 sink = *v.p // ERROR "\*v\.p escapes to heap"
325}
326
327func caller13h() {
328 i := 0 // ERROR "moved to heap: i$"
329 var p *int
330 v := &Val{&p} // ERROR "caller13h &Val literal does not escape$" "caller13h &p does not escape$"
331 v.param13(&i) // ERROR "&i escapes to heap$"
332 sink = **v.p // ERROR "\* \(\*v\.p\) escapes to heap"
333}
David Chase7fbb1b32015-03-26 16:36:15 -0400334
335type Node struct {
336 p *Node
337}
338
339var Sink *Node
340
341func f(x *Node) { // ERROR "leaking param content: x"
342 Sink = &Node{x.p} // ERROR "&Node literal escapes to heap"
343}
344
345func g(x *Node) *Node { // ERROR "leaking param: x to result ~r1 level=0"
346 return &Node{x.p} // ERROR "&Node literal escapes to heap"
347}
348
349func h(x *Node) { // ERROR "leaking param: x"
350 y := &Node{x} // ERROR "h &Node literal does not escape"
351 Sink = g(y)
352 f(y)
353}