fixes ReraiseDefect after typeless except: + finally: (cpp backend)#25777
Open
puffball1567 wants to merge 1 commit intonim-lang:develfrom
Open
fixes ReraiseDefect after typeless except: + finally: (cpp backend)#25777puffball1567 wants to merge 1 commit intonim-lang:develfrom
except: + finally: (cpp backend)#25777puffball1567 wants to merge 1 commit intonim-lang:develfrom
Conversation
[backport]
A bare `except:` followed by a `finally:` block raises a spurious
`ReraiseDefect: no exception to reraise` when compiled with `nim cpp`:
proc test() =
try:
raise newException(CatchableError, "x")
except:
discard
finally:
echo "finally"
test()
Expected output: just `finally` and clean exit.
Actual output:
finally
fatal.nim(53) sysFatal
Error: unhandled exception: no exception to reraise [ReraiseDefect]
This reproduces on every memory manager (arc/orc/refc).
Root cause:
`genTryCpp` emits `try { ... } catch (Exception* T_) { ... }` followed
by a finally block that executes `if (T_) std::rethrow_exception(T_);`.
In the *typed* except branches the codegen explicitly sets
`T_ = nullptr;` once the exception is handled, so the rethrow check
in the finally is a no-op.
The typeless `except:` branch (handled by the `if t[i].len == 1`
arm) emitted only `popCurrentException()` and forgot to clear `T_`.
After the handler body finished, `T_` still pointed at the original
exception, so the trailing `if (T_) std::rethrow_exception(T_);`
rethrew it. By that point Nim's current-exception stack had already
been popped, and the rethrow surfaced as `ReraiseDefect`.
Fix:
Emit `T_ = nullptr;` at the start of the typeless `except:` handler
body, mirroring what is already done for the typed branches. This
is the same one-line treatment that fixed the analogous typed-except
case for nim-lang#5871.
Adds `tests/exception/treraise_typeless_except_finally.nim`, which
runs on `--mm:arc`, `--mm:orc`, and `--mm:refc`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
A bare
except:followed by afinally:block raises a spuriousReraiseDefect: no exception to reraisewhen compiled withnim cpp:Expected output:
Actual output:
This reproduces on every memory manager (
--mm:arc,--mm:orc,--mm:refc).Root cause
genTryCppemitstry { ... } catch (Exception* T_) { ... }followed by a finally block that ends withif (T_) std::rethrow_exception(T_);. In the typed except branches the codegen explicitly setsT_ = nullptr;once the exception is handled, so the rethrow check in the finally is a no-op.The typeless
except:branch (theif t[i].len == 1arm) emitted onlypopCurrentException()and forgot to clearT_. After the handler body finished,T_still pointed at the original exception, so the trailingif (T_) std::rethrow_exception(T_);rethrew it. By that point Nim's current-exception stack had already been popped, and the rethrow surfaced asReraiseDefect.Fix
Emit
T_ = nullptr;at the start of the typelessexcept:handler body, mirroring what is already done for the typed branches. This is the same one-line treatment that fixed the analogous typed-except case for #5871.Tests
Adds
tests/exception/treraise_typeless_except_finally.nim, exercising the bug pattern on--mm:arc,--mm:orc, and--mm:refc.Locally:
tests/exception/— 43 PASS, 0 FAIL, 3 SKIPBackport
Tagged
[backport]in the commit message — the same bug exists inversion-2-2and the fix applies cleanly there.Related
Independent of, but in the same family as, #25775 (also currently open). Both are silent-finally / cpp-backend exception handling fixes; they touch different lines of
genTryCppand don't conflict.