diff --git a/compiler/compiler.go b/compiler/compiler.go index 752e4a5c62..981993fe76 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -1680,6 +1680,10 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c result = b.CreateSelect(cmp, result, arg, "") } return result, nil + case "panic": + // This is rare, but happens in "defer panic()". + b.createRuntimeInvoke("_panic", argValues, "") + return llvm.Value{}, nil case "print", "println": for i, value := range argValues { if i >= 1 && callName == "println" { diff --git a/testdata/recover.go b/testdata/recover.go index ced90cfaee..c7c02c94a4 100644 --- a/testdata/recover.go +++ b/testdata/recover.go @@ -19,6 +19,9 @@ func main() { println("\n# panic replace") panicReplace() + + println("\n# defer panic") + deferPanic() } func recoverSimple() { @@ -89,6 +92,18 @@ func panicReplace() { panic("panic 1") } +func deferPanic() { + defer func() { + printitf("recovered from deferred call:", recover()) + }() + + // This recover should not do anything. + defer recover() + + defer panic("deferred panic") + println("defer panic") +} + func printitf(msg string, itf interface{}) { switch itf := itf.(type) { case string: diff --git a/testdata/recover.txt b/testdata/recover.txt index d276498550..3575058812 100644 --- a/testdata/recover.txt +++ b/testdata/recover.txt @@ -23,3 +23,7 @@ recovered: panic panic 1 panic 2 recovered: panic 2 + +# defer panic +defer panic +recovered from deferred call: deferred panic