blob: c4bf17b2acf2e0ef1c8467a78cb07a0d2a55cc13 [file] [log] [blame]
Luuk van Dijk507fcf32012-10-29 13:38:21 +01001// errorcheck -0 -m -l
2
Emmanuel Odeke53fd5222016-04-10 14:32:26 -07003// Copyright 2012 The Go Authors. All rights reserved.
Luuk van Dijk507fcf32012-10-29 13:38:21 +01004// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test, using compiler diagnostic flags, that the escape analysis is working.
8// Compiles but does not run. Inlining is disabled.
9
10package foo
11
12func noleak(p *int) int { // ERROR "p does not escape"
13 return *p
14}
15
16func leaktoret(p *int) *int { // ERROR "leaking param: p to result"
17 return p
18}
19
Russ Coxa069cf02014-02-13 20:59:39 -050020func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: p to result ~r2"
Luuk van Dijk507fcf32012-10-29 13:38:21 +010021 return p, p
22}
23
Russ Coxa069cf02014-02-13 20:59:39 -050024func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r2" "leaking param: q to result ~r3"
Luuk van Dijk507fcf32012-10-29 13:38:21 +010025 return p, q
26}
27
Russ Coxa069cf02014-02-13 20:59:39 -050028func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
Luuk van Dijk507fcf32012-10-29 13:38:21 +010029 return leaktoret22(q, p)
30}
31
Russ Coxa069cf02014-02-13 20:59:39 -050032func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
Luuk van Dijk507fcf32012-10-29 13:38:21 +010033 r, s := leaktoret22(q, p)
34 return r, s
35}
36
37func leaktoret22d(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
38 r, s = leaktoret22(q, p)
39 return
40}
41
42func leaktoret22e(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
43 r, s = leaktoret22(q, p)
44 return r, s
45}
46
47func leaktoret22f(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
48 rr, ss := leaktoret22(q, p)
49 return rr, ss
50}
51
52var gp *int
53
54func leaktosink(p *int) *int { // ERROR "leaking param: p"
55 gp = p
56 return p
57}
58
59func f1() {
60 var x int
61 p := noleak(&x) // ERROR "&x does not escape"
62 _ = p
63}
64
65func f2() {
66 var x int
67 p := leaktoret(&x) // ERROR "&x does not escape"
68 _ = p
69}
70
71func f3() {
72 var x int // ERROR "moved to heap: x"
73 p := leaktoret(&x) // ERROR "&x escapes to heap"
74 gp = p
75}
76
77func f4() {
78 var x int // ERROR "moved to heap: x"
79 p, q := leaktoret2(&x) // ERROR "&x escapes to heap"
80 gp = p
81 gp = q
82}
83
84func f5() {
85 var x int
86 leaktoret22(leaktoret2(&x)) // ERROR "&x does not escape"
87}
88
89func f6() {
90 var x int // ERROR "moved to heap: x"
91 px1, px2 := leaktoret22(leaktoret2(&x)) // ERROR "&x escapes to heap"
92 gp = px1
93 _ = px2
94}
95
96type T struct{ x int }
97
98func (t *T) Foo(u int) (*T, bool) { // ERROR "leaking param: t to result"
99 t.x += u
100 return t, true
101}
102
103func f7() *T {
104 r, _ := new(T).Foo(42) // ERROR "new.T. escapes to heap"
105 return r
106}
107
108func leakrecursive1(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
109 return leakrecursive2(q, p)
110}
111
112func leakrecursive2(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
113 if *p > *q {
114 return leakrecursive1(q, p)
115 }
116 // without this, leakrecursive? are safe for p and q, b/c in fact their graph does not have leaking edges.
117 return p, q
118}
119
Russ Cox71282132012-11-07 15:15:21 -0500120var global interface{}
121
122type T1 struct {
123 X *int
124}
125
126type T2 struct {
127 Y *T1
128}
129
130func f8(p *T1) (k T2) { // ERROR "leaking param: p to result k" "leaking param: p"
131 if p == nil {
132 k = T2{}
133 return
134 }
135
Dmitry Vyukovedcc0622015-02-19 16:27:32 +0300136 // should make p leak always
137 global = p // ERROR "p escapes to heap"
Russ Cox71282132012-11-07 15:15:21 -0500138 return T2{p}
139}
140
141func f9() {
142 var j T1 // ERROR "moved to heap: j"
David Chasee5060c72015-05-20 15:16:34 -0400143 f8(&j) // ERROR "&j escapes to heap"
Russ Cox71282132012-11-07 15:15:21 -0500144}
Russ Cox1f4d58a2013-08-08 13:46:30 -0400145
146func f10() {
147 // These don't escape but are too big for the stack
David Chasee5060c72015-05-20 15:16:34 -0400148 var x [1 << 30]byte // ERROR "moved to heap: x"
149 var y = make([]byte, 1<<30) // ERROR "make\(\[\]byte, 1 << 30\) escapes to heap"
Russ Cox1f4d58a2013-08-08 13:46:30 -0400150 _ = x[0] + y[0]
151}