From 8b9a1fbdf5c32612d9e258d98eb059b27ad15bfa Mon Sep 17 00:00:00 2001 From: Zvonimir Pavlinovic Date: Tue, 2 Aug 2022 14:48:24 -0700 Subject: [PATCH] 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 TryBot-Result: Gopher Robot gopls-CI: kokoro Reviewed-by: Tim King --- go/callgraph/vta/graph.go | 4 +++- go/callgraph/vta/testdata/src/panic.go | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/go/callgraph/vta/graph.go b/go/callgraph/vta/graph.go index 4d0387f12b..2ad0f89fd8 100644 --- a/go/callgraph/vta/graph.go +++ b/go/callgraph/vta/graph.go @@ -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 } diff --git a/go/callgraph/vta/testdata/src/panic.go b/go/callgraph/vta/testdata/src/panic.go index 2d39c70ea8..5ef3548577 100644 --- a/go/callgraph/vta/testdata/src/panic.go +++ b/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