OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [go.test/] [test/] [recover1.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 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)
}

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.