]> Cypherpunks.ru repositories - gostls13.git/blob - test/escape5.go
all: make copyright headers consistent with one space after period
[gostls13.git] / test / escape5.go
1 // errorcheck -0 -m -l
2
3 // Copyright 2012 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
7 // Test, using compiler diagnostic flags, that the escape analysis is working.
8 // Compiles but does not run.  Inlining is disabled.
9
10 package foo
11
12 func noleak(p *int) int { // ERROR "p does not escape"
13         return *p
14 }
15
16 func leaktoret(p *int) *int { // ERROR "leaking param: p to result"
17         return p
18 }
19
20 func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: p to result ~r2"
21         return p, p
22 }
23
24 func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r2" "leaking param: q to result ~r3"
25         return p, q
26 }
27
28 func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
29         return leaktoret22(q, p)
30 }
31
32 func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
33         r, s := leaktoret22(q, p)
34         return r, s
35 }
36
37 func 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
42 func 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
47 func 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
52 var gp *int
53
54 func leaktosink(p *int) *int { // ERROR "leaking param: p"
55         gp = p
56         return p
57 }
58
59 func f1() {
60         var x int
61         p := noleak(&x) // ERROR "&x does not escape"
62         _ = p
63 }
64
65 func f2() {
66         var x int
67         p := leaktoret(&x) // ERROR "&x does not escape"
68         _ = p
69 }
70
71 func f3() {
72         var x int          // ERROR "moved to heap: x"
73         p := leaktoret(&x) // ERROR "&x escapes to heap"
74         gp = p
75 }
76
77 func 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
84 func f5() {
85         var x int
86         leaktoret22(leaktoret2(&x)) // ERROR "&x does not escape"
87 }
88
89 func 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
96 type T struct{ x int }
97
98 func (t *T) Foo(u int) (*T, bool) { // ERROR "leaking param: t to result"
99         t.x += u
100         return t, true
101 }
102
103 func f7() *T {
104         r, _ := new(T).Foo(42) // ERROR "new.T. escapes to heap"
105         return r
106 }
107
108 func leakrecursive1(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
109         return leakrecursive2(q, p)
110 }
111
112 func 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
120 var global interface{}
121
122 type T1 struct {
123         X *int
124 }
125
126 type T2 struct {
127         Y *T1
128 }
129
130 func 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
136         // should make p leak always
137         global = p // ERROR "p escapes to heap"
138         return T2{p}
139 }
140
141 func f9() {
142         var j T1 // ERROR "moved to heap: j"
143         f8(&j)   // ERROR "&j escapes to heap"
144 }
145
146 func f10() {
147         // These don't escape but are too big for the stack
148         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"
150         _ = x[0] + y[0]
151 }