From 2f7952ff2985bd1061203f2d4a5c421c2e93ccaf Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sun, 4 Aug 2024 15:37:50 +0200 Subject: [PATCH] compiler: support panics inside indirect deferred functions Found this bug while working on WebAssembly recover support. --- compiler/defer.go | 4 ++-- testdata/recover.go | 27 +++++++++++++++++++++++++++ testdata/recover.txt | 6 ++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/compiler/defer.go b/compiler/defer.go index df8686957..1abc34a95 100644 --- a/compiler/defer.go +++ b/compiler/defer.go @@ -528,7 +528,7 @@ func (b *builder) createRunDefers() { forwardParams = append(forwardParams, llvm.Undef(b.dataPtrType)) } - b.createCall(fnType, fnPtr, forwardParams, "") + b.createInvoke(fnType, fnPtr, forwardParams, "") case *ssa.Function: // Direct call. @@ -583,7 +583,7 @@ func (b *builder) createRunDefers() { // Call deferred function. fnType, llvmFn := b.getFunction(fn) - b.createCall(fnType, llvmFn, forwardParams, "") + b.createInvoke(fnType, llvmFn, forwardParams, "") case *ssa.Builtin: db := b.deferBuiltinFuncs[callback] diff --git a/testdata/recover.go b/testdata/recover.go index ced90cfae..725821bfa 100644 --- a/testdata/recover.go +++ b/testdata/recover.go @@ -17,6 +17,12 @@ func main() { println("\n# panic inside defer") panicInsideDefer() + println("\n# panic inside indirect defer") + panicInsideIndirectDefer(callPanic) + + println("\n# panic inside closure") + panicInsideClosure() + println("\n# panic replace") panicReplace() } @@ -77,6 +83,27 @@ func panicInsideDefer() { }() } +func panicInsideIndirectDefer(callback func()) { + defer func() { + printitf("recovered:", recover()) + }() + defer callback() +} + +func callPanic() { + panic("panic") +} + +func panicInsideClosure() { + msg := "panic" + defer func() { + printitf("recovered:", recover()) + }() + defer func() { + panic(msg) + }() +} + func panicReplace() { defer func() { printitf("recovered:", recover()) diff --git a/testdata/recover.txt b/testdata/recover.txt index d27649855..9faf8619e 100644 --- a/testdata/recover.txt +++ b/testdata/recover.txt @@ -19,6 +19,12 @@ recovered 2: foo # panic inside defer recovered: panic +# panic inside indirect defer +recovered: panic + +# panic inside closure +recovered: panic + # panic replace panic 1 panic 2