From ce1e99a260dbcab2ba89ae18c0d5b7b78465448e Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 13 Jun 2014 13:08:35 -0400 Subject: [PATCH] go.tools/go/ssa: emit a recover block if the function's results are unnamed It is easier for clients to recover from panics if the recover block is always present. Otherwise, the client has to work around the lack of a recover block by synthesizing a zero value return. LGTM=adonovan R=adonovan CC=golang-codereviews https://golang.org/cl/87210044 --- go/ssa/builder.go | 11 +++-------- go/ssa/interp/interp.go | 3 --- go/ssa/ssa.go | 6 +++--- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/go/ssa/builder.go b/go/ssa/builder.go index f01d088d..7f6f2c7b 100644 --- a/go/ssa/builder.go +++ b/go/ssa/builder.go @@ -1895,14 +1895,9 @@ start: b.setCall(fn, s.Call, &v.Call) fn.emit(&v) - // A deferred call can cause recovery from panic. - // If the panicking function has named results, - // control resumes at the Recover block to load those - // locals (which may be mutated by the deferred call) - // and return them. - if fn.namedResults != nil { - createRecoverBlock(fn) - } + // A deferred call can cause recovery from panic, + // and control resumes at the Recover block. + createRecoverBlock(fn) case *ast.ReturnStmt: var results []Value diff --git a/go/ssa/interp/interp.go b/go/ssa/interp/interp.go index 60da061a..78866178 100644 --- a/go/ssa/interp/interp.go +++ b/go/ssa/interp/interp.go @@ -555,9 +555,6 @@ func runFrame(fr *frame) { } fr.runDefers() fr.block = fr.fn.Recover - if fr.block == nil { - fr.result = zero(fr.fn.Signature.Results()) - } }() for { diff --git a/go/ssa/ssa.go b/go/ssa/ssa.go index d4d5333b..ce23bbd5 100644 --- a/go/ssa/ssa.go +++ b/go/ssa/ssa.go @@ -273,9 +273,9 @@ type Node interface { // To iterate over the blocks in dominance order, use DomPreorder(). // // Recover is an optional second entry point to which control resumes -// after a recovered panic. The Recover block may contain only a load -// of the function's named return parameters followed by a return of -// the loaded values. +// after a recovered panic. The Recover block may contain only a return +// statement, preceded by a load of the function's named return +// parameters, if any. // // A nested function (Parent()!=nil) that refers to one or more // lexically enclosing local variables ("free variables") has FreeVar