1
0
mirror of https://github.com/golang/go synced 2024-11-26 23:21:22 -07:00
go/test/recover1.go
Emmanuel Odeke 53fd522c0d all: make copyright headers consistent with one space after period
Follows suit with https://go-review.googlesource.com/#/c/20111.

Generated by running
$ grep -R 'Go Authors.  All' * | cut -d":" -f1 | while read F;do perl -pi -e 's/Go
Authors.  All/Go Authors. All/g' $F;done

The code in cmd/internal/unvendor wasn't changed.

Fixes #15213

Change-Id: I4f235cee0a62ec435f9e8540a1ec08ae03b1a75f
Reviewed-on: https://go-review.googlesource.com/21819
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-05-02 13:43:18 +00:00

142 lines
2.5 KiB
Go

// run
// 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 recover during recursive panics.
// Here be dragons.
package main
import "runtime"
func main() {
test1()
test2()
test3()
test4()
test5()
test6()
test7()
}
func die() {
runtime.Breakpoint() // can't depend on panic
}
func mustRecover(x interface{}) {
mustNotRecover() // because it's not a defer call
v := 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 regardless
v = recover()
if v != nil {
println("recover didn't recover")
die()
}
}
func mustNotRecover() {
v := recover()
if v != nil {
println("spurious recover")
die()
}
}
func withoutRecover() {
mustNotRecover() // because it's a sub-call
}
func test1() {
// Easy nested recursive panic.
defer mustRecover(1)
defer func() {
defer mustRecover(2)
panic(2)
}()
panic(1)
}
func test2() {
// Sequential panic.
defer mustNotRecover()
defer func() {
v := recover()
if v == nil || v.(int) != 2 {
println("wrong value", v, 2)
die()
}
defer mustRecover(3)
panic(3)
}()
panic(2)
}
func test3() {
// Sequential panic - like test2 but less picky.
defer mustNotRecover()
defer func() {
recover()
defer mustRecover(3)
panic(3)
}()
panic(2)
}
func test4() {
// Single panic.
defer mustNotRecover()
defer func() {
recover()
}()
panic(4)
}
func test5() {
// Single panic but recover called via defer
defer mustNotRecover()
defer func() {
defer recover()
}()
panic(5)
}
func test6() {
// Sequential panic.
// Like test3, but changed recover to defer (same change as test4 → test5).
defer mustNotRecover()
defer func() {
defer recover() // like a normal call from this func; runs because mustRecover stops the panic
defer mustRecover(3)
panic(3)
}()
panic(2)
}
func test7() {
// Like test6, but swapped defer order.
// The recover in "defer recover()" is now a no-op,
// because it runs called from panic, not from the func,
// and therefore cannot see the panic of 2.
// (Alternately, it cannot see the panic of 2 because
// there is an active panic of 3. And it cannot see the
// panic of 3 because it is at the wrong level (too high on the stack).)
defer mustRecover(2)
defer func() {
defer mustRecover(3)
defer recover() // now a no-op, unlike in test6.
panic(3)
}()
panic(2)
}