go/callgraph/vta: do not assume that recovers cannot be deferred

Otherwise, one has a panic.

Change-Id: I850d99ad373ac877bfbc2a8c2ef0c8ac98992dff
Reviewed-on: https://go-review.googlesource.com/c/tools/+/420914
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Tim King <taking@google.com>
This commit is contained in:
Zvonimir Pavlinovic 2022-08-02 14:48:24 -07:00
Родитель 371fc67d3b
Коммит 8b9a1fbdf5
2 изменённых файлов: 5 добавлений и 2 удалений

Просмотреть файл

@ -568,7 +568,9 @@ func (b *builder) panic(p *ssa.Panic) {
func (b *builder) call(c ssa.CallInstruction) {
// When c is r := recover() call register instruction, we add Recover -> r.
if bf, ok := c.Common().Value.(*ssa.Builtin); ok && bf.Name() == "recover" {
b.addInFlowEdge(recoverReturn{}, b.nodeFromVal(c.(*ssa.Call)))
if v, ok := c.(ssa.Value); ok {
b.addInFlowEdge(recoverReturn{}, b.nodeFromVal(v))
}
return
}

3
go/callgraph/vta/testdata/src/panic.go поставляемый
Просмотреть файл

@ -27,12 +27,12 @@ func recover2() {
func Baz(a A) {
defer recover1()
defer recover()
panic(a)
}
// Relevant SSA:
// func recover1():
// 0:
// t0 = print("only this recover...":string)
// t1 = recover()
// t2 = typeassert,ok t1.(I)
@ -53,6 +53,7 @@ func Baz(a A) {
// t0 = local A (a)
// *t0 = a
// defer recover1()
// defer recover()
// t1 = *t0
// t2 = make interface{} <- A (t1)
// panic t2