Source file
test/recover.go
1
2
3
4
5
6
7
8
9 package main
10
11 import (
12 "os"
13 "reflect"
14 "runtime"
15 )
16
17 func main() {
18
19
20
21 interp := os.Getenv("GOSSAINTERP") != ""
22
23 test1()
24 test1WithClosures()
25 test2()
26 test3()
27 if !interp {
28 test4()
29 }
30 test5()
31 test6()
32 test6WithClosures()
33 test7()
34 test8()
35 test9()
36 if !interp {
37 test9reflect1()
38 test9reflect2()
39 }
40 test10()
41 if !interp {
42 test10reflect1()
43 test10reflect2()
44 }
45 test11()
46 if !interp {
47 test11reflect1()
48 test11reflect2()
49 }
50 test111()
51 test12()
52 if !interp {
53 test12reflect1()
54 test12reflect2()
55 }
56 test13()
57 if !interp {
58 test13reflect1()
59 test13reflect2()
60 }
61 test14()
62 if !interp {
63 test14reflect1()
64 test14reflect2()
65 test15()
66 test16()
67 }
68 }
69
70 func die() {
71 runtime.Breakpoint()
72 }
73
74 func mustRecoverBody(v1, v2, v3, x interface{}) {
75 v := v1
76 if v != nil {
77 println("spurious recover", v)
78 die()
79 }
80 v = v2
81 if v == nil {
82 println("missing recover", x.(int))
83 die()
84 }
85 if v != x {
86 println("wrong value", v, x)
87 die()
88 }
89
90
91 v = v3
92 if v != nil {
93 println("recover didn't recover")
94 die()
95 }
96 }
97
98 func doubleRecover() interface{} {
99 return recover()
100 }
101
102 func mustRecover(x interface{}) {
103 mustRecoverBody(doubleRecover(), recover(), recover(), x)
104 }
105
106 func mustNotRecover() {
107 v := recover()
108 if v != nil {
109 println("spurious recover", v)
110 die()
111 }
112 }
113
114 func withoutRecover() {
115 mustNotRecover()
116 }
117
118 func withoutRecoverRecursive(n int) {
119 if n == 0 {
120 withoutRecoverRecursive(1)
121 } else {
122 v := recover()
123 if v != nil {
124 println("spurious recover (recursive)", v)
125 die()
126 }
127 }
128 }
129
130 func test1() {
131 defer mustNotRecover()
132 defer mustRecover(1)
133 defer withoutRecover()
134 defer withoutRecoverRecursive(0)
135 panic(1)
136 }
137
138
139
140
141
142
143 func test1WithClosures() {
144 defer func() {
145 v := recover()
146 if v != nil {
147 println("spurious recover in closure")
148 die()
149 }
150 }()
151 defer func(x interface{}) {
152 mustNotRecover()
153 v := recover()
154 if v == nil {
155 println("missing recover", x.(int))
156 die()
157 }
158 if v != x {
159 println("wrong value", v, x)
160 die()
161 }
162 }(1)
163 defer func() {
164 mustNotRecover()
165 }()
166 panic(1)
167 }
168
169 func test2() {
170
171
172
173
174 defer mustRecover(2)
175 defer recover()
176 panic(2)
177 }
178
179 func test3() {
180 defer mustNotRecover()
181 defer func() {
182 recover()
183 }()
184 panic(3)
185 }
186
187 func test4() {
188
189 defer mustNotRecover()
190 defer func() {
191 defer recover()
192 }()
193 panic(4)
194 }
195
196
197
198 func try(g func(), deflt interface{}) (x interface{}) {
199 defer func() {
200 if v := recover(); v != nil {
201 x = v
202 }
203 }()
204 defer g()
205 return deflt
206 }
207
208
209
210 func try1(g func(), deflt interface{}) (x interface{}) {
211 defer func() {
212 if v := recover(); v != nil {
213 x = v
214 }
215 }()
216 defer g()
217 x = deflt
218 return
219 }
220
221 func test5() {
222 v := try(func() { panic(5) }, 55).(int)
223 if v != 5 {
224 println("wrong value", v, 5)
225 die()
226 }
227
228 s := try(func() {}, "hi").(string)
229 if s != "hi" {
230 println("wrong value", s, "hi")
231 die()
232 }
233
234 v = try1(func() { panic(5) }, 55).(int)
235 if v != 5 {
236 println("try1 wrong value", v, 5)
237 die()
238 }
239
240 s = try1(func() {}, "hi").(string)
241 if s != "hi" {
242 println("try1 wrong value", s, "hi")
243 die()
244 }
245 }
246
247
248
249
250
251 func big(mustRecover bool) {
252 var x [100000]int
253 x[0] = 1
254 x[99999] = 1
255 _ = x
256
257 v := recover()
258 if mustRecover {
259 if v == nil {
260 println("missing big recover")
261 die()
262 }
263 } else {
264 if v != nil {
265 println("spurious big recover")
266 die()
267 }
268 }
269 }
270
271 func test6() {
272 defer big(false)
273 defer big(true)
274 panic(6)
275 }
276
277 func test6WithClosures() {
278 defer func() {
279 var x [100000]int
280 x[0] = 1
281 x[99999] = 1
282 _ = x
283 if recover() != nil {
284 println("spurious big closure recover")
285 die()
286 }
287 }()
288 defer func() {
289 var x [100000]int
290 x[0] = 1
291 x[99999] = 1
292 _ = x
293 if recover() == nil {
294 println("missing big closure recover")
295 die()
296 }
297 }()
298 panic("6WithClosures")
299 }
300
301 func test7() {
302 ok := false
303 func() {
304
305
306
307
308 defer func() { ok = true }()
309 defer mustRecover(7)
310 panic(7)
311 }()
312 if !ok {
313 println("did not run ok func")
314 die()
315 }
316 }
317
318 func varargs(s *int, a ...int) {
319 *s = 0
320 for _, v := range a {
321 *s += v
322 }
323 if recover() != nil {
324 *s += 100
325 }
326 }
327
328 func test8a() (r int) {
329 defer varargs(&r, 1, 2, 3)
330 panic(0)
331 }
332
333 func test8b() (r int) {
334 defer varargs(&r, 4, 5, 6)
335 return
336 }
337
338 func test8() {
339 if test8a() != 106 || test8b() != 15 {
340 println("wrong value")
341 die()
342 }
343 }
344
345 type I interface {
346 M()
347 }
348
349
350 type T1 struct{}
351
352 func (*T1) M() {
353 mustRecoverBody(doubleRecover(), recover(), recover(), 9)
354 }
355
356 func test9() {
357 var i I = &T1{}
358 defer i.M()
359 panic(9)
360 }
361
362 func test9reflect1() {
363 f := reflect.ValueOf(&T1{}).Method(0).Interface().(func())
364 defer f()
365 panic(9)
366 }
367
368 func test9reflect2() {
369 f := reflect.TypeOf(&T1{}).Method(0).Func.Interface().(func(*T1))
370 defer f(&T1{})
371 panic(9)
372 }
373
374
375 type T2 uintptr
376
377 func (T2) M() {
378 mustRecoverBody(doubleRecover(), recover(), recover(), 10)
379 }
380
381 func test10() {
382 var i I = T2(0)
383 defer i.M()
384 panic(10)
385 }
386
387 func test10reflect1() {
388 f := reflect.ValueOf(T2(0)).Method(0).Interface().(func())
389 defer f()
390 panic(10)
391 }
392
393 func test10reflect2() {
394 f := reflect.TypeOf(T2(0)).Method(0).Func.Interface().(func(T2))
395 defer f(T2(0))
396 panic(10)
397 }
398
399
400 type T3 struct{}
401
402 func (T3) M() {
403 mustRecoverBody(doubleRecover(), recover(), recover(), 11)
404 }
405
406 func test11() {
407 var i I = T3{}
408 defer i.M()
409 panic(11)
410 }
411
412 func test11reflect1() {
413 f := reflect.ValueOf(T3{}).Method(0).Interface().(func())
414 defer f()
415 panic(11)
416 }
417
418 func test11reflect2() {
419 f := reflect.TypeOf(T3{}).Method(0).Func.Interface().(func(T3))
420 defer f(T3{})
421 panic(11)
422 }
423
424
425 type T3deeper struct{}
426
427 func (T3deeper) M() {
428 badstate()
429 mustRecoverBody(doubleRecover(), recover(), recover(), 111)
430 }
431
432 func test111() {
433 var i I = T3deeper{}
434 defer i.M()
435 panic(111)
436 }
437
438 type Tiny struct{}
439
440 func (Tiny) M() {
441 panic(112)
442 }
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459 func badstate() {
460 defer func() {
461 recover()
462 }()
463 var i I = Tiny{}
464 i.M()
465 }
466
467
468 type T4 [2]string
469
470 func (T4) M() {
471 mustRecoverBody(doubleRecover(), recover(), recover(), 12)
472 }
473
474 func test12() {
475 var i I = T4{}
476 defer i.M()
477 panic(12)
478 }
479
480 func test12reflect1() {
481 f := reflect.ValueOf(T4{}).Method(0).Interface().(func())
482 defer f()
483 panic(12)
484 }
485
486 func test12reflect2() {
487 f := reflect.TypeOf(T4{}).Method(0).Func.Interface().(func(T4))
488 defer f(T4{})
489 panic(12)
490 }
491
492
493 type T5 [8192]byte
494
495 func (T5) M() {
496 mustRecoverBody(doubleRecover(), recover(), recover(), 13)
497 }
498
499 func test13() {
500 var i I = T5{}
501 defer i.M()
502 panic(13)
503 }
504
505 func test13reflect1() {
506 f := reflect.ValueOf(T5{}).Method(0).Interface().(func())
507 defer f()
508 panic(13)
509 }
510
511 func test13reflect2() {
512 f := reflect.TypeOf(T5{}).Method(0).Func.Interface().(func(T5))
513 defer f(T5{})
514 panic(13)
515 }
516
517
518
519
520 type T6 [8192]byte
521
522 var global byte
523
524 func (T6) M() {
525 var x [8192]byte
526 x[0] = 1
527 x[1] = 2
528 for i := range x {
529 global += x[i]
530 }
531 mustRecoverBody(doubleRecover(), recover(), recover(), 14)
532 }
533
534 func test14() {
535 var i I = T6{}
536 defer i.M()
537 panic(14)
538 }
539
540 func test14reflect1() {
541 f := reflect.ValueOf(T6{}).Method(0).Interface().(func())
542 defer f()
543 panic(14)
544 }
545
546 func test14reflect2() {
547 f := reflect.TypeOf(T6{}).Method(0).Func.Interface().(func(T6))
548 defer f(T6{})
549 panic(14)
550 }
551
552
553
554 func reflectFunc(args []reflect.Value) (results []reflect.Value) {
555 mustRecoverBody(doubleRecover(), recover(), recover(), 15)
556 return nil
557 }
558
559 func test15() {
560 f := reflect.MakeFunc(reflect.TypeOf((func())(nil)), reflectFunc).Interface().(func())
561 defer f()
562 panic(15)
563 }
564
565 func reflectFunc2(args []reflect.Value) (results []reflect.Value) {
566
567 args[0].Interface().(func())()
568 return nil
569 }
570
571 func reflectFunc3(args []reflect.Value) (results []reflect.Value) {
572 if v := recover(); v != nil {
573 println("spurious recover", v)
574 die()
575 }
576 return nil
577 }
578
579 func test16() {
580 defer mustRecover(16)
581
582 f2 := reflect.MakeFunc(reflect.TypeOf((func(func()))(nil)), reflectFunc2).Interface().(func(func()))
583 f3 := reflect.MakeFunc(reflect.TypeOf((func())(nil)), reflectFunc3).Interface().(func())
584 defer f2(f3)
585
586 panic(16)
587 }
588
View as plain text