diff --git a/_test/issue-1022.go b/_test/issue-1022.go new file mode 100644 index 000000000..6aa1a388c --- /dev/null +++ b/_test/issue-1022.go @@ -0,0 +1,17 @@ +package main + +import "fmt" + +func main() { + defer func() { + r := recover() + if r != nil { + fmt.Println(r) + } + }() + + panic("Ho Ho Ho!") +} + +// Output: +// Ho Ho Ho! diff --git a/interp/run.go b/interp/run.go index caca54911..dc2092755 100644 --- a/interp/run.go +++ b/interp/run.go @@ -3381,46 +3381,56 @@ func isNil(n *node) { tnext := getExec(n.tnext) dest := genValue(n) - if n.fnext != nil { - fnext := getExec(n.fnext) - if c0.typ.cat == interfaceT { + if n.fnext == nil { + if c0.typ.cat != interfaceT { n.exec = func(f *frame) bltn { - v := value(f) - vi, ok := v.Interface().(valueInterface) - if ok && (vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT) || v.IsNil() { - dest(f).SetBool(true) - return tnext - } - dest(f).SetBool(false) - return fnext + dest(f).SetBool(value(f).IsNil()) + return tnext } - } else { - n.exec = func(f *frame) bltn { - if value(f).IsNil() { - dest(f).SetBool(true) - return tnext - } - dest(f).SetBool(false) - return fnext + return + } + n.exec = func(f *frame) bltn { + v := value(f) + if vi, ok := v.Interface().(valueInterface); ok { + dest(f).SetBool(vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT) + } else { + dest(f).SetBool(v.IsNil()) } + return tnext } - } else { - if c0.typ.cat == interfaceT { - n.exec = func(f *frame) bltn { - v := value(f) - if vi, ok := v.Interface().(valueInterface); ok { - dest(f).SetBool(vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT) - } else { - dest(f).SetBool(v.IsNil()) - } + return + } + + fnext := getExec(n.fnext) + + if c0.typ.cat != interfaceT { + n.exec = func(f *frame) bltn { + if value(f).IsNil() { + dest(f).SetBool(true) return tnext } - } else { - n.exec = func(f *frame) bltn { - dest(f).SetBool(value(f).IsNil()) + dest(f).SetBool(false) + return fnext + } + return + } + + n.exec = func(f *frame) bltn { + v := value(f) + if vi, ok := v.Interface().(valueInterface); ok { + if (vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT) { + dest(f).SetBool(true) return tnext } + dest(f).SetBool(false) + return fnext } + if v.IsNil() { + dest(f).SetBool(true) + return tnext + } + dest(f).SetBool(false) + return fnext } } @@ -3435,46 +3445,57 @@ func isNotNil(n *node) { tnext := getExec(n.tnext) dest := genValue(n) - if n.fnext != nil { - fnext := getExec(n.fnext) - if c0.typ.cat == interfaceT { + if n.fnext == nil { + if c0.typ.cat != interfaceT { n.exec = func(f *frame) bltn { - v := value(f) - vi, ok := v.Interface().(valueInterface) - if ok && (vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT) || v.IsNil() { - dest(f).SetBool(false) - return fnext - } - dest(f).SetBool(true) + dest(f).SetBool(!value(f).IsNil()) return tnext } - } else { - n.exec = func(f *frame) bltn { - if value(f).IsNil() { - dest(f).SetBool(false) - return fnext - } - dest(f).SetBool(true) - return tnext + return + } + + n.exec = func(f *frame) bltn { + v := value(f) + if vi, ok := v.Interface().(valueInterface); ok { + dest(f).SetBool(!(vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT)) + } else { + dest(f).SetBool(!v.IsNil()) } + return tnext } - } else { - if c0.typ.cat == interfaceT { - n.exec = func(f *frame) bltn { - v := value(f) - if vi, ok := v.Interface().(valueInterface); ok { - dest(f).SetBool(!(vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT)) - } else { - dest(f).SetBool(!v.IsNil()) - } - return tnext + return + } + + fnext := getExec(n.fnext) + + if c0.typ.cat != interfaceT { + n.exec = func(f *frame) bltn { + if value(f).IsNil() { + dest(f).SetBool(false) + return fnext } - } else { - n.exec = func(f *frame) bltn { - dest(f).SetBool(!value(f).IsNil()) - return tnext + dest(f).SetBool(true) + return tnext + } + return + } + + n.exec = func(f *frame) bltn { + v := value(f) + if vi, ok := v.Interface().(valueInterface); ok { + if (vi == valueInterface{} || vi.node.kind == basicLit && vi.node.typ.cat == nilT) { + dest(f).SetBool(false) + return fnext } + dest(f).SetBool(true) + return tnext + } + if v.IsNil() { + dest(f).SetBool(false) + return fnext } + dest(f).SetBool(true) + return tnext } }