126 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			Go
		
	
	
	
// 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()
 | 
						|
}
 |