Skip to content

Commit 449eefd

Browse files
committed
compiler: allow deferred panic
This is rare, but apparently some programs do this: defer panic("...") This is emitted in the IR as a builtin function.
1 parent 058f62a commit 449eefd

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

compiler/compiler.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,6 +1680,10 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
16801680
result = b.CreateSelect(cmp, result, arg, "")
16811681
}
16821682
return result, nil
1683+
case "panic":
1684+
// This is rare, but happens in "defer panic()".
1685+
b.createRuntimeInvoke("_panic", argValues, "")
1686+
return llvm.Value{}, nil
16831687
case "print", "println":
16841688
for i, value := range argValues {
16851689
if i >= 1 && callName == "println" {

testdata/recover.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ func main() {
1919

2020
println("\n# panic replace")
2121
panicReplace()
22+
23+
println("\n# defer panic")
24+
deferPanic()
2225
}
2326

2427
func recoverSimple() {
@@ -89,6 +92,18 @@ func panicReplace() {
8992
panic("panic 1")
9093
}
9194

95+
func deferPanic() {
96+
defer func() {
97+
printitf("recovered from deferred call:", recover())
98+
}()
99+
100+
// This recover should not do anything.
101+
defer recover()
102+
103+
defer panic("deferred panic")
104+
println("defer panic")
105+
}
106+
92107
func printitf(msg string, itf interface{}) {
93108
switch itf := itf.(type) {
94109
case string:

testdata/recover.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ recovered: panic
2323
panic 1
2424
panic 2
2525
recovered: panic 2
26+
27+
# defer panic
28+
defer panic
29+
recovered from deferred call: deferred panic

0 commit comments

Comments
 (0)