]> Cypherpunks.ru repositories - gostls13.git/blob - test/escape_iface.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / escape_iface.go
1 // errorcheck -0 -m -l
2
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.
6
7 // Test escape analysis for interface conversions.
8
9 package escape
10
11 var sink interface{}
12
13 type M interface {
14         M()
15 }
16
17 func mescapes(m M) { // ERROR "leaking param: m"
18         sink = m
19 }
20
21 func mdoesnotescape(m M) { // ERROR "m does not escape"
22 }
23
24 // Tests for type stored directly in iface and with value receiver method.
25 type M0 struct {
26         p *int
27 }
28
29 func (M0) M() {
30 }
31
32 func efaceEscape0() {
33         {
34                 i := 0
35                 v := M0{&i}
36                 var x M = v
37                 _ = x
38         }
39         {
40                 i := 0 // ERROR "moved to heap: i"
41                 v := M0{&i}
42                 var x M = v
43                 sink = x
44         }
45         {
46                 i := 0
47                 v := M0{&i}
48                 var x M = v
49                 v1 := x.(M0)
50                 _ = v1
51         }
52         {
53                 i := 0 // ERROR "moved to heap: i"
54                 v := M0{&i}
55                 // BAD: v does not escape to heap here
56                 var x M = v
57                 v1 := x.(M0)
58                 sink = v1
59         }
60         {
61                 i := 0
62                 v := M0{&i}
63                 var x M = v
64                 x.M() // ERROR "devirtualizing x.M"
65         }
66         {
67                 i := 0 // ERROR "moved to heap: i"
68                 v := M0{&i}
69                 var x M = v
70                 mescapes(x)
71         }
72         {
73                 i := 0
74                 v := M0{&i}
75                 var x M = v
76                 mdoesnotescape(x)
77         }
78 }
79
80 // Tests for type stored indirectly in iface and with value receiver method.
81 type M1 struct {
82         p *int
83         x int
84 }
85
86 func (M1) M() {
87 }
88
89 func efaceEscape1() {
90         {
91                 i := 0
92                 v := M1{&i, 0}
93                 var x M = v // ERROR "v does not escape"
94                 _ = x
95         }
96         {
97                 i := 0 // ERROR "moved to heap: i"
98                 v := M1{&i, 0}
99                 var x M = v // ERROR "v escapes to heap"
100                 sink = x
101         }
102         {
103                 i := 0
104                 v := M1{&i, 0}
105                 var x M = v // ERROR "v does not escape"
106                 v1 := x.(M1)
107                 _ = v1
108         }
109         {
110                 i := 0 // ERROR "moved to heap: i"
111                 v := M1{&i, 0}
112                 var x M = v // ERROR "v does not escape"
113                 v1 := x.(M1)
114                 sink = v1 // ERROR "v1 escapes to heap"
115         }
116         {
117                 i := 0
118                 v := M1{&i, 0}
119                 var x M = v // ERROR "v does not escape"
120                 x.M()       // ERROR "devirtualizing x.M"
121         }
122         {
123                 i := 0 // ERROR "moved to heap: i"
124                 v := M1{&i, 0}
125                 var x M = v // ERROR "v escapes to heap"
126                 mescapes(x)
127         }
128         {
129                 i := 0
130                 v := M1{&i, 0}
131                 var x M = v // ERROR "v does not escape"
132                 mdoesnotescape(x)
133         }
134 }
135
136 // Tests for type stored directly in iface and with pointer receiver method.
137 type M2 struct {
138         p *int
139 }
140
141 func (*M2) M() {
142 }
143
144 func efaceEscape2() {
145         {
146                 i := 0
147                 v := &M2{&i} // ERROR "&M2{...} does not escape"
148                 var x M = v
149                 _ = x
150         }
151         {
152                 i := 0       // ERROR "moved to heap: i"
153                 v := &M2{&i} // ERROR "&M2{...} escapes to heap"
154                 var x M = v
155                 sink = x
156         }
157         {
158                 i := 0
159                 v := &M2{&i} // ERROR "&M2{...} does not escape"
160                 var x M = v
161                 v1 := x.(*M2)
162                 _ = v1
163         }
164         {
165                 i := 0       // ERROR "moved to heap: i"
166                 v := &M2{&i} // ERROR "&M2{...} escapes to heap"
167                 // BAD: v does not escape to heap here
168                 var x M = v
169                 v1 := x.(*M2)
170                 sink = v1
171         }
172         {
173                 i := 0       // ERROR "moved to heap: i"
174                 v := &M2{&i} // ERROR "&M2{...} does not escape"
175                 // BAD: v does not escape to heap here
176                 var x M = v
177                 v1 := x.(*M2)
178                 sink = *v1
179         }
180         {
181                 i := 0       // ERROR "moved to heap: i"
182                 v := &M2{&i} // ERROR "&M2{...} does not escape"
183                 // BAD: v does not escape to heap here
184                 var x M = v
185                 v1, ok := x.(*M2)
186                 sink = *v1
187                 _ = ok
188         }
189         {
190                 i := 0
191                 v := &M2{&i} // ERROR "&M2{...} does not escape"
192                 var x M = v
193                 x.M() // ERROR "devirtualizing x.M"
194         }
195         {
196                 i := 0       // ERROR "moved to heap: i"
197                 v := &M2{&i} // ERROR "&M2{...} escapes to heap"
198                 var x M = v
199                 mescapes(x)
200         }
201         {
202                 i := 0
203                 v := &M2{&i} // ERROR "&M2{...} does not escape"
204                 var x M = v
205                 mdoesnotescape(x)
206         }
207 }
208
209 type T1 struct {
210         p *int
211 }
212
213 type T2 struct {
214         T1 T1
215 }
216
217 func dotTypeEscape() *T2 { // #11931
218         var x interface{}
219         x = &T1{p: new(int)} // ERROR "new\(int\) escapes to heap" "&T1{...} does not escape"
220         return &T2{          // ERROR "&T2{...} escapes to heap"
221                 T1: *(x.(*T1)),
222         }
223 }
224
225 func dotTypeEscape2() { // #13805, #15796
226         {
227                 i := 0
228                 j := 0
229                 var v int
230                 var ok bool
231                 var x interface{} = i // ERROR "i does not escape"
232                 var y interface{} = j // ERROR "j does not escape"
233
234                 *(&v) = x.(int)
235                 *(&v), *(&ok) = y.(int)
236         }
237         { // #13805, #15796
238                 i := 0
239                 j := 0
240                 var ok bool
241                 var x interface{} = i // ERROR "i does not escape"
242                 var y interface{} = j // ERROR "j does not escape"
243
244                 sink = x.(int)         // ERROR "x.\(int\) escapes to heap"
245                 sink, *(&ok) = y.(int) // ERROR "autotmp_.* escapes to heap"
246         }
247         {
248                 i := 0 // ERROR "moved to heap: i"
249                 j := 0 // ERROR "moved to heap: j"
250                 var ok bool
251                 var x interface{} = &i
252                 var y interface{} = &j
253
254                 sink = x.(*int)
255                 sink, *(&ok) = y.(*int)
256         }
257 }
258
259 func issue42279() {
260         type I interface{ M() }
261         type T struct{ I }
262
263         var i I = T{} // ERROR "T\{\} does not escape"
264         i.M()         // ERROR "partially devirtualizing i.M to T"
265 }