// RUN: llgo -o %t %s // RUN: %t 2>&1 | FileCheck %s // CHECK: f2.1 // CHECK-NEXT: f5 // CHECK-NEXT: recovered no error // CHECK-NEXT: f5 // CHECK-NEXT: recovered: meep meep // CHECK-NEXT: 888 // CHECK-NEXT: f5 // CHECK-NEXT: recovered no error // CHECK-NEXT: f5 // CHECK-NEXT: recovered no error // CHECK-NEXT: 888 // CHECK-NEXT: 456 // CHECK-NEXT: 999 // CHECK-NEXT: 999 // CHECK-NEXT: 123 // CHECK-NEXT: 999 // CHECK-NEXT: 999 // CHECK-NEXT: 246 // CHECK-NEXT: f2.2 // CHECK-NEXT: f2.3 // CHECK-NEXT: f1.1 // CHECK-NEXT: f1.2 // CHECK-NEXT: recovered: second // CHECK-NEXT: ahoy package main type T struct { value int } type T1 struct { T } func (t T) abc() { println(t.value) } func (t *T) def() { println(t.value) } func (t *T) ghi(v int) { println(v) } func printerr(err interface{}) { if err != nil { println("recovered:", err.(string)) } else { println("recovered no error") } } func f6() { defer func() { printerr(recover()) }() defer func() { panic("second") }() panic("first") } func f5(panic_ bool) { var t1 T1 t1.T.value = 888 defer t1.abc() var f func(int) f = func(recursion int) { if recursion > 0 { f(recursion - 1) return } println("f5") printerr(recover()) } defer f(0) // will recover (after f(1)) defer f(1) // won't recover if panic_ { panic("meep meep") } } func f4() { var a T = T{999} var b *T = &a defer a.abc() defer a.def() defer a.ghi(123) defer b.abc() defer b.def() defer b.ghi(456) f5(true) f5(false) // verify the recover in f5 works } func f3() (a int) { defer func() { a *= 2 }() f4() return 123 } func f2() { defer func() { println("f2.3") }() defer func(s string) { println(s) }("f2.2") println("f2.1") println(f3()) } func f1() { defer func() { println("f1.2") }() defer func() { println("f1.1") }() f2() } func builtins() { defer println("ahoy") } func main() { f1() f6() builtins() }