2018-01-24 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / testsuite / go.test / test / recover1.go
blobb763a10741746eeec64f2ccde024a469a9c3ce2e
1 // run
3 // Copyright 2010 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.
7 // Test of recover during recursive panics.
8 // Here be dragons.
10 package main
12 import "runtime"
14 func main() {
15 test1()
16 test2()
17 test3()
18 test4()
19 test5()
20 test6()
21 test7()
24 func die() {
25 runtime.Breakpoint() // can't depend on panic
28 func mustRecover(x interface{}) {
29 mustNotRecover() // because it's not a defer call
30 v := recover()
31 if v == nil {
32 println("missing recover")
33 die() // panic is useless here
35 if v != x {
36 println("wrong value", v, x)
37 die()
40 // the value should be gone now regardless
41 v = recover()
42 if v != nil {
43 println("recover didn't recover")
44 die()
48 func mustNotRecover() {
49 v := recover()
50 if v != nil {
51 println("spurious recover")
52 die()
56 func withoutRecover() {
57 mustNotRecover() // because it's a sub-call
60 func test1() {
61 // Easy nested recursive panic.
62 defer mustRecover(1)
63 defer func() {
64 defer mustRecover(2)
65 panic(2)
66 }()
67 panic(1)
70 func test2() {
71 // Sequential panic.
72 defer mustNotRecover()
73 defer func() {
74 v := recover()
75 if v == nil || v.(int) != 2 {
76 println("wrong value", v, 2)
77 die()
79 defer mustRecover(3)
80 panic(3)
81 }()
82 panic(2)
85 func test3() {
86 // Sequential panic - like test2 but less picky.
87 defer mustNotRecover()
88 defer func() {
89 recover()
90 defer mustRecover(3)
91 panic(3)
92 }()
93 panic(2)
96 func test4() {
97 // Single panic.
98 defer mustNotRecover()
99 defer func() {
100 recover()
102 panic(4)
105 func test5() {
106 // Single panic but recover called via defer
107 defer mustNotRecover()
108 defer func() {
109 defer recover()
111 panic(5)
114 func test6() {
115 // Sequential panic.
116 // Like test3, but changed recover to defer (same change as test4 → test5).
117 defer mustNotRecover()
118 defer func() {
119 defer recover() // like a normal call from this func; runs because mustRecover stops the panic
120 defer mustRecover(3)
121 panic(3)
123 panic(2)
126 func test7() {
127 // Like test6, but swapped defer order.
128 // The recover in "defer recover()" is now a no-op,
129 // because it runs called from panic, not from the func,
130 // and therefore cannot see the panic of 2.
131 // (Alternately, it cannot see the panic of 2 because
132 // there is an active panic of 3. And it cannot see the
133 // panic of 3 because it is at the wrong level (too high on the stack).)
134 defer mustRecover(2)
135 defer func() {
136 defer mustRecover(3)
137 defer recover() // now a no-op, unlike in test6.
138 panic(3)
140 panic(2)