aboutsummaryrefslogtreecommitdiff
path: root/go/callgraph/vta/testdata/src/panic.go
blob: 2d39c70ea8910b53133b1eb61466ef2ff4cb73f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright 2021 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.

// go:build ignore

package testdata

type I interface {
	foo()
}

type A struct{}

func (a A) foo() {}

func recover1() {
	print("only this recover should execute")
	if r, ok := recover().(I); ok {
		r.foo()
	}
}

func recover2() {
	recover()
}

func Baz(a A) {
	defer recover1()
	panic(a)
}

// Relevant SSA:
// func recover1():
// 	0:
//   t0 = print("only this recover...":string)
//   t1 = recover()
//   t2 = typeassert,ok t1.(I)
//   t3 = extract t2 #0
//   t4 = extract t2 #1
//   if t4 goto 1 else 2
//  1:
//   t5 = invoke t3.foo()
//   jump 2
//  2:
//   return
//
// func recover2():
//   t0 = recover()
//   return
//
// func Baz(i I):
//   t0 = local A (a)
//   *t0 = a
//   defer recover1()
//   t1 = *t0
//   t2 = make interface{} <- A (t1)
//   panic t2

// t2 argument to panic in Baz gets ultimately connected to recover
// registers t1 in recover1() and t0 in recover2().

// WANT:
// Panic -> Recover
// Local(t2) -> Panic
// Recover -> Local(t0), Local(t1)