URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [go.test/] [test/] [recover.go] - Rev 700
Compare with Previous | Blame | View Log
// $G $D/$F.go && $L $F.$A && ./$A.out// Copyright 2010 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// Test of basic recover functionality.package mainimport "runtime"func main() {test1()test1WithClosures()test2()test3()test4()test5()test6()test6WithClosures()test7()}func die() {runtime.Breakpoint() // can't depend on panic}func mustRecover(x interface{}) {mustNotRecover() // because it's not a defer callv := recover()if v == nil {println("missing recover")die() // panic is useless here}if v != x {println("wrong value", v, x)die()}// the value should be gone now regardlessv = recover()if v != nil {println("recover didn't recover")die()}}func mustNotRecover() {v := recover()if v != nil {println("spurious recover", v)die()}}func withoutRecover() {mustNotRecover() // because it's a sub-call}func test1() {defer mustNotRecover() // because mustRecover will squelch itdefer mustRecover(1) // because of panic belowdefer withoutRecover() // should be no-op, leaving for mustRecover to findpanic(1)}// Repeat test1 with closures instead of standard function.// Interesting because recover bases its decision// on the frame pointer of its caller, and a closure's// frame pointer is in the middle of its actual arguments// (after the hidden ones for the closed-over variables).func test1WithClosures() {defer func() {v := recover()if v != nil {println("spurious recover in closure")die()}}()defer func(x interface{}) {mustNotRecover()v := recover()if v == nil {println("missing recover")die()}if v != x {println("wrong value", v, x)die()}}(1)defer func() {mustNotRecover()}()panic(1)}func test2() {// Recover only sees the panic argument// if it is called from a deferred call.// It does not see the panic when called from a call within a deferred call (too late)// nor does it see the panic when it *is* the deferred call (too early).defer mustRecover(2)defer recover() // should be no-oppanic(2)}func test3() {defer mustNotRecover()defer func() {recover() // should squelch}()panic(3)}func test4() {// Equivalent to test3 but using defer to make the call.defer mustNotRecover()defer func() {defer recover() // should squelch}()panic(4)}// Check that closures can set output arguments.// Run g(). If it panics, return x; else return deflt.func try(g func(), deflt interface{}) (x interface{}) {defer func() {if v := recover(); v != nil {x = v}}()defer g()return deflt}// Check that closures can set output arguments.// Run g(). If it panics, return x; else return deflt.func try1(g func(), deflt interface{}) (x interface{}) {defer func() {if v := recover(); v != nil {x = v}}()defer g()x = defltreturn}func test5() {v := try(func() { panic(5) }, 55).(int)if v != 5 {println("wrong value", v, 5)die()}s := try(func() {}, "hi").(string)if s != "hi" {println("wrong value", s, "hi")die()}v = try1(func() { panic(5) }, 55).(int)if v != 5 {println("try1 wrong value", v, 5)die()}s = try1(func() {}, "hi").(string)if s != "hi" {println("try1 wrong value", s, "hi")die()}}// When a deferred big call starts, it must first// create yet another stack segment to hold the// giant frame for x. Make sure that doesn't// confuse recover.func big(mustRecover bool) {var x [100000]intx[0] = 1x[99999] = 1_ = xv := recover()if mustRecover {if v == nil {println("missing big recover")die()}} else {if v != nil {println("spurious big recover")die()}}}func test6() {defer big(false)defer big(true)panic(6)}func test6WithClosures() {defer func() {var x [100000]intx[0] = 1x[99999] = 1_ = xif recover() != nil {println("spurious big closure recover")die()}}()defer func() {var x [100000]intx[0] = 1x[99999] = 1_ = xif recover() == nil {println("missing big closure recover")die()}}()panic("6WithClosures")}func test7() {ok := falsefunc() {// should panic, then call mustRecover 7, which stops the panic.// then should keep processing ordinary defers earlier than that one// before returning.// this test checks that the defer func on the next line actually runs.defer func() { ok = true }()defer mustRecover(7)panic(7)}()if !ok {println("did not run ok func")die()}}
