3 // Copyright 2015 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
7 // Test escape analysis for function parameters.
9 // In this test almost everything is BAD except the simplest cases
10 // where input directly flows to output.
14 func zero() int { return 0 }
19 func param0(p *int) *int { // ERROR "leaking param: p to result ~r1"
25 _ = param0(&i) // ERROR "caller0a &i does not escape$"
29 i := 0 // ERROR "moved to heap: i$"
30 sink = param0(&i) // ERROR "&i escapes to heap$" "param0\(&i\) escapes to heap"
34 func param1(p1, p2 *int) (*int, *int) { // ERROR "leaking param: p1 to result ~r2" "leaking param: p2 to result ~r3"
39 i := 0 // ERROR "moved to heap: i$"
41 sink, _ = param1(&i, &j) // ERROR "&i escapes to heap$" "caller1 &j does not escape$"
45 func param2(p1 *int, p2 **int) { // ERROR "leaking param: p1$" "param2 p2 does not escape$"
50 i := 0 // ERROR "moved to heap: i$"
52 param2(&i, &p) // ERROR "&i escapes to heap$" "caller2a &p does not escape$"
57 i := 0 // ERROR "moved to heap: i$"
59 param2(&i, &p) // ERROR "&i escapes to heap$" "caller2b &p does not escape$"
60 sink = p // ERROR "p escapes to heap$"
63 func paramArraySelfAssign(p *PairOfPairs) { // ERROR "p does not escape"
64 p.pairs[0] = p.pairs[1] // ERROR "ignoring self-assignment in p.pairs\[0\] = p.pairs\[1\]"
67 func paramArraySelfAssignUnsafeIndex(p *PairOfPairs) { // ERROR "leaking param content: p"
68 // Function call inside index disables self-assignment case to trigger.
69 p.pairs[zero()] = p.pairs[1]
70 p.pairs[zero()+1] = p.pairs[1]
73 type PairOfPairs struct {
77 type BoxedPair struct {
81 type WrappedPair struct {
85 func leakParam(x interface{}) { // ERROR "leaking param: x"
89 func sinkAfterSelfAssignment1(box *BoxedPair) { // ERROR "leaking param content: box"
90 box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
91 sink = box.pair.p2 // ERROR "box.pair.p2 escapes to heap"
94 func sinkAfterSelfAssignment2(box *BoxedPair) { // ERROR "leaking param content: box"
95 box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
96 sink = box.pair // ERROR "box.pair escapes to heap"
99 func sinkAfterSelfAssignment3(box *BoxedPair) { // ERROR "leaking param content: box"
100 box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
101 leakParam(box.pair.p2) // ERROR "box.pair.p2 escapes to heap"
104 func sinkAfterSelfAssignment4(box *BoxedPair) { // ERROR "leaking param content: box"
105 box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
106 leakParam(box.pair) // ERROR "box.pair escapes to heap"
109 func selfAssignmentAndUnrelated(box1, box2 *BoxedPair) { // ERROR "leaking param content: box2" "box1 does not escape"
110 box1.pair.p1 = box1.pair.p2 // ERROR "ignoring self-assignment in box1.pair.p1 = box1.pair.p2"
111 leakParam(box2.pair.p2) // ERROR "box2.pair.p2 escapes to heap"
114 func notSelfAssignment1(box1, box2 *BoxedPair) { // ERROR "leaking param content: box2" "box1 does not escape"
115 box1.pair.p1 = box2.pair.p1
118 func notSelfAssignment2(p1, p2 *PairOfPairs) { // ERROR "leaking param content: p2" "p1 does not escape"
119 p1.pairs[0] = p2.pairs[1]
122 func notSelfAssignment3(p1, p2 *PairOfPairs) { // ERROR "leaking param content: p2" "p1 does not escape"
123 p1.pairs[0].p1 = p2.pairs[1].p1
126 func boxedPairSelfAssign(box *BoxedPair) { // ERROR "box does not escape"
127 box.pair.p1 = box.pair.p2 // ERROR "ignoring self-assignment in box.pair.p1 = box.pair.p2"
130 func wrappedPairSelfAssign(w *WrappedPair) { // ERROR "w does not escape"
131 w.pair.p1 = w.pair.p2 // ERROR "ignoring self-assignment in w.pair.p1 = w.pair.p2"
140 func param3(p *Pair) { // ERROR "param3 p does not escape"
141 p.p1 = p.p2 // ERROR "param3 ignoring self-assignment in p.p1 = p.p2"
147 p := Pair{&i, &j} // ERROR "caller3a &i does not escape" "caller3a &j does not escape"
148 param3(&p) // ERROR "caller3a &p does not escape"
153 i := 0 // ERROR "moved to heap: i$"
154 j := 0 // ERROR "moved to heap: j$"
155 p := Pair{&i, &j} // ERROR "&i escapes to heap$" "&j escapes to heap$"
156 param3(&p) // ERROR "caller3b &p does not escape"
157 sink = p // ERROR "p escapes to heap$"
161 func (p *Pair) param4(i *int) { // ERROR "\(\*Pair\).param4 p does not escape$" "leaking param: i$"
166 i := 0 // ERROR "moved to heap: i$"
168 p.param4(&i) // ERROR "&i escapes to heap$" "caller4a p does not escape$"
173 i := 0 // ERROR "moved to heap: i$"
175 p.param4(&i) // ERROR "&i escapes to heap$" "caller4b p does not escape$"
176 sink = p // ERROR "p escapes to heap$"
180 func param5(i *int) { // ERROR "leaking param: i$"
181 sink = i // ERROR "i escapes to heap$"
185 i := 0 // ERROR "moved to heap: i$"
186 param5(&i) // ERROR "&i escapes to heap$"
190 func param6(i ***int) { // ERROR "leaking param content: i$"
191 sink = *i // ERROR "\*i escapes to heap$"
195 i := 0 // ERROR "moved to heap: i$"
196 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
197 p2 := &p // ERROR "&p escapes to heap$"
198 param6(&p2) // ERROR "caller6a &p2 does not escape"
202 func param7(i ***int) { // ERROR "leaking param content: i$"
203 sink = **i // ERROR "\* \(\*i\) escapes to heap"
207 i := 0 // ERROR "moved to heap: i$"
208 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
209 p2 := &p // ERROR "&p escapes to heap$"
210 param7(&p2) // ERROR "caller7 &p2 does not escape"
214 func param8(i **int) { // ERROR "param8 i does not escape$"
215 sink = **i // ERROR "\* \(\*i\) escapes to heap"
220 p := &i // ERROR "caller8 &i does not escape$"
221 param8(&p) // ERROR "caller8 &p does not escape$"
225 func param9(p ***int) **int { // ERROR "leaking param: p to result ~r1 level=1"
231 p := &i // ERROR "caller9a &i does not escape"
232 p2 := &p // ERROR "caller9a &p does not escape"
233 _ = param9(&p2) // ERROR "caller9a &p2 does not escape$"
237 i := 0 // ERROR "moved to heap: i$"
238 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
239 p2 := &p // ERROR "&p escapes to heap$"
240 sink = param9(&p2) // ERROR "caller9b &p2 does not escape$" "param9\(&p2\) escapes to heap"
244 func param10(p ***int) *int { // ERROR "leaking param: p to result ~r1 level=2"
250 p := &i // ERROR "caller10a &i does not escape"
251 p2 := &p // ERROR "caller10a &p does not escape"
252 _ = param10(&p2) // ERROR "caller10a &p2 does not escape$"
256 i := 0 // ERROR "moved to heap: i$"
257 p := &i // ERROR "&i escapes to heap$"
258 p2 := &p // ERROR "caller10b &p does not escape$"
259 sink = param10(&p2) // ERROR "caller10b &p2 does not escape$" "param10\(&p2\) escapes to heap"
262 // in escapes to heap (address of param taken and returned)
263 func param11(i **int) ***int { // ERROR "moved to heap: i$"
264 return &i // ERROR "&i escapes to heap$"
268 i := 0 // ERROR "moved to heap: i"
269 p := &i // ERROR "moved to heap: p" "&i escapes to heap"
270 _ = param11(&p) // ERROR "&p escapes to heap"
274 i := 0 // ERROR "moved to heap: i$"
275 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
276 sink = param11(&p) // ERROR "&p escapes to heap$" "param11\(&p\) escapes to heap"
279 func caller11c() { // GOOD
280 i := 0 // ERROR "moved to heap: i$"
281 p := &i // ERROR "moved to heap: p" "&i escapes to heap"
282 sink = *param11(&p) // ERROR "&p escapes to heap" "\*param11\(&p\) escapes to heap"
286 i := 0 // ERROR "moved to heap: i$"
287 p := &i // ERROR "&i escapes to heap" "moved to heap: p"
288 p2 := &p // ERROR "&p escapes to heap"
289 sink = param11(p2) // ERROR "param11\(p2\) escapes to heap"
297 func (r *Indir) param12(i **int) { // ERROR "\(\*Indir\).param12 r does not escape$" "moved to heap: i$"
298 r.p = &i // ERROR "&i escapes to heap$"
302 i := 0 // ERROR "moved to heap: i$"
303 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
305 r.param12(&p) // ERROR "&p escapes to heap$" "caller12a r does not escape$"
310 i := 0 // ERROR "moved to heap: i$"
311 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
312 r := &Indir{} // ERROR "caller12b &Indir literal does not escape$"
313 r.param12(&p) // ERROR "&p escapes to heap$"
318 i := 0 // ERROR "moved to heap: i$"
319 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
321 r.param12(&p) // ERROR "&p escapes to heap$" "caller12c r does not escape$"
322 sink = r // ERROR "r escapes to heap$"
326 i := 0 // ERROR "moved to heap: i$"
327 p := &i // ERROR "&i escapes to heap$" "moved to heap: p$"
329 r.param12(&p) // ERROR "&p escapes to heap$" "caller12d r does not escape$"
330 sink = **r.p // ERROR "\* \(\*r\.p\) escapes to heap"
338 func (v Val) param13(i *int) { // ERROR "Val.param13 v does not escape$" "leaking param: i$"
343 i := 0 // ERROR "moved to heap: i$"
346 v.p = &p // ERROR "caller13a &p does not escape$"
347 v.param13(&i) // ERROR "&i escapes to heap$"
352 i := 0 // ERROR "moved to heap: i$"
354 v := Val{&p} // ERROR "caller13b &p does not escape$"
355 v.param13(&i) // ERROR "&i escapes to heap$"
360 i := 0 // ERROR "moved to heap: i$"
362 v := &Val{&p} // ERROR "caller13c &Val literal does not escape$" "caller13c &p does not escape$"
363 v.param13(&i) // ERROR "&i escapes to heap$"
368 i := 0 // ERROR "moved to heap: i$"
369 var p *int // ERROR "moved to heap: p$"
371 v.p = &p // ERROR "&p escapes to heap$"
372 v.param13(&i) // ERROR "&i escapes to heap$"
373 sink = v // ERROR "v escapes to heap$"
377 i := 0 // ERROR "moved to heap: i$"
378 var p *int // ERROR "moved to heap: p$"
379 v := Val{&p} // ERROR "&p escapes to heap$"
380 v.param13(&i) // ERROR "&i escapes to heap$"
381 sink = v // ERROR "v escapes to heap$"
385 i := 0 // ERROR "moved to heap: i$"
386 var p *int // ERROR "moved to heap: p$"
387 v := &Val{&p} // ERROR "&Val literal escapes to heap$" "&p escapes to heap$"
388 v.param13(&i) // ERROR "&i escapes to heap$"
389 sink = v // ERROR "v escapes to heap$"
393 i := 0 // ERROR "moved to heap: i$"
395 v := Val{&p} // ERROR "caller13g &p does not escape$"
396 v.param13(&i) // ERROR "&i escapes to heap$"
397 sink = *v.p // ERROR "\*v\.p escapes to heap"
401 i := 0 // ERROR "moved to heap: i$"
403 v := &Val{&p} // ERROR "caller13h &Val literal does not escape$" "caller13h &p does not escape$"
404 v.param13(&i) // ERROR "&i escapes to heap$"
405 sink = **v.p // ERROR "\* \(\*v\.p\) escapes to heap"
414 func f(x *Node) { // ERROR "leaking param content: x"
415 Sink = &Node{x.p} // ERROR "&Node literal escapes to heap"
418 func g(x *Node) *Node { // ERROR "leaking param: x to result ~r1 level=0"
419 return &Node{x.p} // ERROR "&Node literal escapes to heap"
422 func h(x *Node) { // ERROR "leaking param: x"
423 y := &Node{x} // ERROR "h &Node literal does not escape"