libgo: update to Go1.14beta1
[platform/upstream/gcc.git] / libgo / go / runtime / testdata / testprog / deadlock.go
index 5f0d120..105d6a5 100644 (file)
@@ -22,6 +22,9 @@ func init() {
        register("StackOverflow", StackOverflow)
        register("ThreadExhaustion", ThreadExhaustion)
        register("RecursivePanic", RecursivePanic)
+       register("RecursivePanic2", RecursivePanic2)
+       register("RecursivePanic3", RecursivePanic3)
+       register("RecursivePanic4", RecursivePanic4)
        register("GoexitExit", GoexitExit)
        register("GoNil", GoNil)
        register("MainGoroutineID", MainGoroutineID)
@@ -29,6 +32,8 @@ func init() {
        register("GoexitInPanic", GoexitInPanic)
        register("PanicAfterGoexit", PanicAfterGoexit)
        register("RecoveredPanicAfterGoexit", RecoveredPanicAfterGoexit)
+       register("RecoverBeforePanicAfterGoexit", RecoverBeforePanicAfterGoexit)
+       register("RecoverBeforePanicAfterGoexit2", RecoverBeforePanicAfterGoexit2)
        register("PanicTraceback", PanicTraceback)
        register("GoschedInPanic", GoschedInPanic)
        register("SyscallInPanic", SyscallInPanic)
@@ -111,6 +116,50 @@ func RecursivePanic() {
        panic("again")
 }
 
+// Same as RecursivePanic, but do the first recover and the second panic in
+// separate defers, and make sure they are executed in the correct order.
+func RecursivePanic2() {
+       func() {
+               defer func() {
+                       fmt.Println(recover())
+               }()
+               var x [8192]byte
+               func(x [8192]byte) {
+                       defer func() {
+                               panic("second panic")
+                       }()
+                       defer func() {
+                               fmt.Println(recover())
+                       }()
+                       panic("first panic")
+               }(x)
+       }()
+       panic("third panic")
+}
+
+// Make sure that the first panic finished as a panic, even though the second
+// panic was recovered
+func RecursivePanic3() {
+       defer func() {
+               defer func() {
+                       recover()
+               }()
+               panic("second panic")
+       }()
+       panic("first panic")
+}
+
+// Test case where a single defer recovers one panic but starts another panic. If
+// the second panic is never recovered, then the recovered first panic will still
+// appear on the panic stack (labeled '[recovered]') and the runtime stack.
+func RecursivePanic4() {
+       defer func() {
+               recover()
+               panic("second panic")
+       }()
+       panic("first panic")
+}
+
 func GoexitExit() {
        println("t1")
        go func() {
@@ -202,6 +251,50 @@ func RecoveredPanicAfterGoexit() {
        runtime.Goexit()
 }
 
+func RecoverBeforePanicAfterGoexit() {
+       // 1. defer a function that recovers
+       // 2. defer a function that panics
+       // 3. call goexit
+       // Goexit runs the #2 defer. Its panic
+       // is caught by the #1 defer.  For Goexit, we explicitly
+       // resume execution in the Goexit loop, instead of resuming
+       // execution in the caller (which would make the Goexit disappear!)
+       defer func() {
+               r := recover()
+               if r == nil {
+                       panic("bad recover")
+               }
+       }()
+       defer func() {
+               panic("hello")
+       }()
+       runtime.Goexit()
+}
+
+func RecoverBeforePanicAfterGoexit2() {
+       for i := 0; i < 2; i++ {
+               defer func() {
+               }()
+       }
+       // 1. defer a function that recovers
+       // 2. defer a function that panics
+       // 3. call goexit
+       // Goexit runs the #2 defer. Its panic
+       // is caught by the #1 defer.  For Goexit, we explicitly
+       // resume execution in the Goexit loop, instead of resuming
+       // execution in the caller (which would make the Goexit disappear!)
+       defer func() {
+               r := recover()
+               if r == nil {
+                       panic("bad recover")
+               }
+       }()
+       defer func() {
+               panic("hello")
+       }()
+       runtime.Goexit()
+}
+
 func PanicTraceback() {
        pt1()
 }