go.tools/ssa/interp: fix bug: recovered panic without NRPs should return zero values.
+ test. R=gri CC=golang-dev https://golang.org/cl/38040043
This commit is contained in:
parent
d063887ea0
commit
100638985b
|
|
@ -532,9 +532,13 @@ func callSSA(i *interpreter, caller *frame, callpos token.Pos, fn *ssa.Function,
|
|||
// After a normal return, fr.result contains the result of the call
|
||||
// and fr.block is nil.
|
||||
//
|
||||
// After a recovered panic, fr.result is undefined and fr.block
|
||||
// contains the block at which to resume control, which may be
|
||||
// nil for a normal return.
|
||||
// A recovered panic in a function without named return parameters
|
||||
// (NRPs) becomes a normal return of the zero value of the function's
|
||||
// result type.
|
||||
//
|
||||
// After a recovered panic in a function with NRPs, fr.result is
|
||||
// undefined and fr.block contains the block at which to resume
|
||||
// control.
|
||||
//
|
||||
func runFrame(fr *frame) {
|
||||
defer func() {
|
||||
|
|
@ -550,7 +554,10 @@ func runFrame(fr *frame) {
|
|||
fmt.Fprintf(os.Stderr, "Panicking: %T %v.\n", fr.panic, fr.panic)
|
||||
}
|
||||
fr.runDefers()
|
||||
fr.block = fr.fn.Recover // recovered panic
|
||||
fr.block = fr.fn.Recover
|
||||
if fr.block == nil {
|
||||
fr.result = zero(fr.fn.Signature.Results())
|
||||
}
|
||||
}()
|
||||
|
||||
for {
|
||||
|
|
|
|||
|
|
@ -235,6 +235,15 @@ func zero(t types.Type) value {
|
|||
s[i] = zero(t.Field(i).Type())
|
||||
}
|
||||
return s
|
||||
case *types.Tuple:
|
||||
if t.Len() == 1 {
|
||||
return zero(t.At(0).Type())
|
||||
}
|
||||
s := make(tuple, t.Len())
|
||||
for i := range s {
|
||||
s[i] = zero(t.At(i).Type())
|
||||
}
|
||||
return s
|
||||
case *types.Chan:
|
||||
return chan value(nil)
|
||||
case *types.Map:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ package main
|
|||
|
||||
// Tests of panic/recover.
|
||||
|
||||
import "fmt"
|
||||
|
||||
func fortyTwo() (r int) {
|
||||
r = 42
|
||||
// The next two statements simulate a 'return' statement.
|
||||
|
|
@ -9,8 +11,24 @@ func fortyTwo() (r int) {
|
|||
panic(nil)
|
||||
}
|
||||
|
||||
func zero() int {
|
||||
defer func() { recover() }()
|
||||
panic(1)
|
||||
}
|
||||
|
||||
func zeroEmpty() (int, string) {
|
||||
defer func() { recover() }()
|
||||
panic(1)
|
||||
}
|
||||
|
||||
func main() {
|
||||
if r := fortyTwo(); r != 42 {
|
||||
panic(r)
|
||||
}
|
||||
if r := zero(); r != 0 {
|
||||
panic(r)
|
||||
}
|
||||
if r, s := zeroEmpty(); r != 0 || s != "" {
|
||||
panic(fmt.Sprint(r, s))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue