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 basic recover functionality.
21 // exp/ssa/interp still has some bugs in recover().
22 if os
.Getenv("GOSSAINTERP") == "" {
32 runtime
.Breakpoint() // can't depend on panic
35 func mustRecover(x
interface{}) {
36 mustNotRecover() // because it's not a defer call
39 println("missing recover")
40 die() // panic is useless here
43 println("wrong value", v
, x
)
47 // the value should be gone now regardless
50 println("recover didn't recover")
55 func mustNotRecover() {
58 println("spurious recover", v
)
63 func withoutRecover() {
64 mustNotRecover() // because it's a sub-call
68 defer mustNotRecover() // because mustRecover will squelch it
69 defer mustRecover(1) // because of panic below
70 defer withoutRecover() // should be no-op, leaving for mustRecover to find
74 // Repeat test1 with closures instead of standard function.
75 // Interesting because recover bases its decision
76 // on the frame pointer of its caller, and a closure's
77 // frame pointer is in the middle of its actual arguments
78 // (after the hidden ones for the closed-over variables).
79 func test1WithClosures() {
83 println("spurious recover in closure")
87 defer func(x
interface{}) {
91 println("missing recover")
95 println("wrong value", v
, x
)
106 // Recover only sees the panic argument
107 // if it is called from a deferred call.
108 // It does not see the panic when called from a call within a deferred call (too late)
109 // nor does it see the panic when it *is* the deferred call (too early).
111 defer recover() // should be no-op
116 defer mustNotRecover()
118 recover() // should squelch
124 // Equivalent to test3 but using defer to make the call.
125 defer mustNotRecover()
127 defer recover() // should squelch
132 // Check that closures can set output arguments.
133 // Run g(). If it panics, return x; else return deflt.
134 func try(g
func(), deflt
interface{}) (x
interface{}) {
136 if v
:= recover(); v
!= nil {
144 // Check that closures can set output arguments.
145 // Run g(). If it panics, return x; else return deflt.
146 func try1(g
func(), deflt
interface{}) (x
interface{}) {
148 if v
:= recover(); v
!= nil {
158 v
:= try(func() { panic(5) }, 55).(int)
160 println("wrong value", v
, 5)
164 s
:= try(func() {}, "hi").(string)
166 println("wrong value", s
, "hi")
170 v
= try1(func() { panic(5) }, 55).(int)
172 println("try1 wrong value", v
, 5)
176 s
= try1(func() {}, "hi").(string)
178 println("try1 wrong value", s
, "hi")
183 // When a deferred big call starts, it must first
184 // create yet another stack segment to hold the
185 // giant frame for x. Make sure that doesn't
187 func big(mustRecover
bool) {
196 println("missing big recover")
201 println("spurious big recover")
213 func test6WithClosures() {
219 if recover() != nil {
220 println("spurious big closure recover")
229 if recover() == nil {
230 println("missing big closure recover")
234 panic("6WithClosures")
240 // should panic, then call mustRecover 7, which stops the panic.
241 // then should keep processing ordinary defers earlier than that one
243 // this test checks that the defer func on the next line actually runs.
244 defer func() { ok
= true }()
249 println("did not run ok func")
254 func varargs(s
*int, a
...int) {
256 for _
, v
:= range a
{
259 if recover() != nil {
264 func test8a() (r
int) {
265 defer varargs(&r
, 1, 2, 3)
269 func test8b() (r
int) {
270 defer varargs(&r
, 4, 5, 6)
275 if test8a() != 106 ||
test8b() != 15 {
276 println("wrong value")