Source file
test/escape_closure.go
1
2
3
4
5
6
7
8
9 package escape
10
11 var sink interface{}
12
13 func ClosureCallArgs0() {
14 x := 0
15 func(p *int) {
16 *p = 1
17 }(&x)
18 }
19
20 func ClosureCallArgs1() {
21 x := 0
22 for {
23 func(p *int) {
24 *p = 1
25 }(&x)
26 }
27 }
28
29 func ClosureCallArgs2() {
30 for {
31 x := 0
32 func(p *int) {
33 *p = 1
34 }(&x)
35 }
36 }
37
38 func ClosureCallArgs3() {
39 x := 0
40 func(p *int) {
41 sink = p
42 }(&x)
43 }
44
45 func ClosureCallArgs4() {
46 x := 0
47 _ = func(p *int) *int {
48 return p
49 }(&x)
50 }
51
52 func ClosureCallArgs5() {
53 x := 0
54
55
56 sink = func(p *int) *int {
57 return p
58 }(&x)
59 }
60
61 func ClosureCallArgs6() {
62 x := 0
63 func(p *int) {
64 sink = &p
65 }(&x)
66 }
67
68 func ClosureCallArgs7() {
69 var pp *int
70 for {
71 x := 0
72 func(p *int) {
73 pp = p
74 }(&x)
75 }
76 _ = pp
77 }
78
79 func ClosureCallArgs8() {
80 x := 0
81 defer func(p *int) {
82 *p = 1
83 }(&x)
84 }
85
86 func ClosureCallArgs9() {
87
88 x := 0
89 for {
90 defer func(p *int) {
91 *p = 1
92 }(&x)
93 }
94 }
95
96 func ClosureCallArgs10() {
97 for {
98 x := 0
99 defer func(p *int) {
100 *p = 1
101 }(&x)
102 }
103 }
104
105 func ClosureCallArgs11() {
106 x := 0
107 defer func(p *int) {
108 sink = p
109 }(&x)
110 }
111
112 func ClosureCallArgs12() {
113 x := 0
114 defer func(p *int) *int {
115 return p
116 }(&x)
117 }
118
119 func ClosureCallArgs13() {
120 x := 0
121 defer func(p *int) {
122 sink = &p
123 }(&x)
124 }
125
126 func ClosureCallArgs14() {
127 x := 0
128 p := &x
129 _ = func(p **int) *int {
130 return *p
131 }(&p)
132 }
133
134 func ClosureCallArgs15() {
135 x := 0
136 p := &x
137 sink = func(p **int) *int {
138 return *p
139 }(&p)
140 }
141
142 func ClosureLeak1(s string) string {
143 t := s + "YYYY"
144 return ClosureLeak1a(t)
145 }
146
147
148 func ClosureLeak1a(a ...string) string {
149 return func() string {
150 return a[0]
151 }()
152 }
153
154 func ClosureLeak2(s string) string {
155 t := s + "YYYY"
156 c := ClosureLeak2a(t)
157 return c
158 }
159 func ClosureLeak2a(a ...string) string {
160 return ClosureLeak2b(func() string {
161 return a[0]
162 })
163 }
164 func ClosureLeak2b(f func() string) string {
165 return f()
166 }
167
168 func ClosureIndirect() {
169 f := func(p *int) {}
170 f(new(int))
171
172 g := f
173 g(new(int))
174
175 h := nopFunc
176 h(new(int))
177 }
178
179 func nopFunc(p *int) {}
180
181 func ClosureIndirect2() {
182 f := func(p *int) *int { return p }
183
184 f(new(int))
185
186 g := f
187 g(new(int))
188
189 h := nopFunc2
190 h(new(int))
191 }
192
193 func nopFunc2(p *int) *int { return p }
194
195 func ClosureIndirectDeclAssign() {
196 var f func(p *int)
197 f = func(p *int) {}
198 f(new(int))
199 }
200
201 func ClosureIndirectDeclAssign2() {
202 var f func(p *int) *int
203 f = func(p *int) *int { return p }
204 f(new(int))
205 }
206
207 func ClosureIndirectDeclAssign3() {
208 var f func(p *int)
209 f = func(p *int) {
210 sink = p
211 }
212 f(new(int))
213 }
214
215 func ClosureIndirectDeclReassign() {
216 var f func(p *int)
217 f = func(p *int) {}
218 f = func(p *int) {
219 sink = p
220 }
221 f(new(int))
222 }
223
224 func ClosureIndirectDeclRecursive() {
225 var visit func(p *int)
226 visit = func(p *int) {
227 visit(p)
228 }
229 visit(new(int))
230 }
231
232 func ClosureIndirectNilInit() {
233 var f func(p *int) = nil
234 f = func(p *int) {}
235 f(new(int))
236 }
237
238 func ClosureIndirectTypedNilInit() {
239 var f func(p *int) = (func(*int))(nil)
240 f = func(p *int) {}
241 f(new(int))
242 }
243
244 func ClosureIndirectNestedAssign() {
245 var f func(p *int)
246 func() {
247 f = func(p *int) {}
248 }()
249 f(new(int))
250 }
251
252 func ClosureIndirectNestedAssignLeak() {
253 var f func(p *int)
254 func() {
255 f = func(p *int) {
256 sink = p
257 }
258 }()
259 f(new(int))
260 }
261
262 func ClosureIndirectTypeSwitch() {
263 foo := any(func(a *int) { sink = a })
264 switch foo := foo.(type) {
265 case func(a *int):
266 foo(new(int))
267 }
268 }
269
270 func ClosureIndirectTypeSwitchReassign() {
271 foo := any(func(a *int) { sink = a })
272 switch foo := foo.(type) {
273 case func(a *int):
274 foo = func(a *int) {}
275 foo(new(int))
276 }
277 }
278
279 func ClosureIndirectNilReassign() {
280 var f func(p *int)
281 f = nil
282 f = func(p *int) {}
283 f(new(int))
284 }
285
286 func ClosureIndirectMultiAssign(b bool) {
287 var f func(p *int)
288 if b {
289 f = func(p *int) {}
290 } else {
291 f = func(p *int) {}
292 }
293 f(new(int))
294 }
295
296 func ClosureIndirectMultiAssignNamed(b bool) {
297 var f func(*int)
298 if b {
299 f = nopFunc
300 } else {
301 f = nopFunc
302 }
303 f(new(int))
304 }
305
306 func ClosureIndirectMultiAssignResult(b bool) *int {
307 var f func(p *int) *int
308 if b {
309 f = func(p *int) *int { return p }
310 } else {
311 f = func(p *int) *int { return p }
312 }
313 return f(new(int))
314 }
315
316 func ClosureIndirectMultiAssignSafe(b bool) int {
317 var f func(p *int) int
318 if b {
319 f = func(p *int) int { return *p }
320 } else {
321 f = func(p *int) int { return 42 }
322 }
323 return f(new(int))
324 }
325
326 func ClosureIndirectTripleAssign(x int) {
327 var f func(p *int)
328 switch x {
329 case 1:
330 f = func(p *int) {}
331 case 2:
332 f = func(p *int) {}
333 default:
334 f = func(p *int) {}
335 }
336 f(new(int))
337 }
338
339 func ClosureIndirectReassignInit(b bool) {
340 f := func(p *int) {}
341 if b {
342 f = func(p *int) {}
343 }
344 f(new(int))
345 }
346
347 func ClosureIndirectNestedMultiAssign(b bool) {
348 var f func(p *int)
349 f = func(p *int) {}
350 func() {
351 f = func(p *int) {}
352 }()
353 f(new(int))
354 }
355
356 type myFloat struct{ v float64 }
357
358 func (f *myFloat) add(p *myFloat) *myFloat {
359 f.v += p.v
360 return f
361 }
362
363 func (f *myFloat) sub(p *myFloat) *myFloat {
364 f.v -= p.v
365 return f
366 }
367
368 func ClosureIndirectMethodExpr(b bool) {
369 var op func(*myFloat, *myFloat) *myFloat
370 if b {
371 op = (*myFloat).add
372 } else {
373 op = (*myFloat).sub
374 }
375 f := &myFloat{1.0}
376 g := &myFloat{2.0}
377 op(f, g)
378 }
379
380 func ClosureIndirectMethodExprMixed(b bool) {
381 var op func(*myFloat, *myFloat) *myFloat
382 if b {
383 op = (*myFloat).add
384 } else {
385 op = func(f, g *myFloat) *myFloat {
386 return nil
387 }
388 }
389 f := &myFloat{1.0}
390 g := &myFloat{2.0}
391 op(f, g)
392 }
393
View as plain text