diff --git a/go/ssa/builder.go b/go/ssa/builder.go index be55bdb6..fcf320ed 100644 --- a/go/ssa/builder.go +++ b/go/ssa/builder.go @@ -1918,24 +1918,7 @@ start: // locals (which may be mutated by the deferred call) // and return them. if fn.namedResults != nil { - // Optimization: if we can prove the deferred call - // won't cause recovery from panic, we can avoid a - // Recover block. - // We scan the callee for calls to recover() iff: - // - it's a static call - // - to a function in the same package - // (other packages' SSA building happens concurrently) - // - whose SSA building has started (Blocks != nil) - // - and finished (i.e. not this function) - // NB, this is always true for: defer func() { ... } () - // - // TODO(adonovan): optimize interpackage cases, e.g. - // (sync.Mutex).Unlock(), (io.Closer).Close - if callee, ok := v.Call.Value.(*Function); ok && callee.Pkg == fn.Pkg && callee != fn && callee.Blocks != nil && !callsRecover(callee) { - // Deferred call cannot cause recovery from panic. - } else { - createRecoverBlock(fn) - } + createRecoverBlock(fn) } case *ast.ReturnStmt: diff --git a/go/ssa/util.go b/go/ssa/util.go index 3c661c36..56220aba 100644 --- a/go/ssa/util.go +++ b/go/ssa/util.go @@ -103,22 +103,6 @@ func logStack(format string, args ...interface{}) func() { } } -// callsRecover reports whether f contains a direct call to recover(). -func callsRecover(f *Function) bool { - for _, b := range f.Blocks { - for _, instr := range b.Instrs { - if call, ok := instr.(*Call); ok { - if blt, ok := call.Call.Value.(*Builtin); ok { - if blt.Name() == "recover" { - return true - } - } - } - } - } - return false -} - // newVar creates a 'var' for use in a types.Tuple. func newVar(name string, typ types.Type) *types.Var { return types.NewParam(token.NoPos, nil, name, typ)