* fixes #11118

* Reset closure iter exception before rethrowing
This commit is contained in:
Andreas Rumpf 2019-08-17 10:37:38 +02:00 • committed by GitHub
commit db9e27dffd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 14 deletions

View file

@ -90,9 +90,6 @@
# :unrollFinally = true # :unrollFinally = true
# goto nearestFinally (or -1 if not exists) # goto nearestFinally (or -1 if not exists)
# #
# Every finally block calls closureIterEndFinally() upon its successful
# completion.
#
# Example: # Example:
# #
# try: # try:
@ -126,6 +123,7 @@
# if :curExc.isNil: # if :curExc.isNil:
# return :tmpResult # return :tmpResult
# else: # else:
# closureIterSetupExc(nil)
# raise # raise
# state = -1 # Goto next state. In this case we just exit # state = -1 # Goto next state. In this case we just exit
# break :stateLoop # break :stateLoop
@ -809,10 +807,11 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
let retStmt = newTree(nkReturnStmt, asgn) let retStmt = newTree(nkReturnStmt, asgn)
let branch = newTree(nkElifBranch, cmp, retStmt) let branch = newTree(nkElifBranch, cmp, retStmt)
# The C++ backend requires `getCurrentException` here. let nullifyExc = newTree(nkCall, newSymNode(ctx.g.getCompilerProc("closureIterSetupExc")), nilnode)
let raiseStmt = newTree(nkRaiseStmt, ctx.g.callCodegenProc("getCurrentException")) nullifyExc.info = info
let raiseStmt = newTree(nkRaiseStmt, curExc)
raiseStmt.info = info raiseStmt.info = info
let elseBranch = newTree(nkElse, raiseStmt) let elseBranch = newTree(nkElse, newTree(nkStmtList, nullifyExc, raiseStmt))
let ifBody = newTree(nkIfStmt, branch, elseBranch) let ifBody = newTree(nkIfStmt, branch, elseBranch)
let elifBranch = newTree(nkElifBranch, ctx.newUnrollFinallyAccess(info), ifBody) let elifBranch = newTree(nkElifBranch, ctx.newUnrollFinallyAccess(info), ifBody)

View file

@ -136,8 +136,7 @@ proc popCurrentExceptionEx(id: uint) {.compilerRtl.} =
prev.up = cur.up prev.up = cur.up
proc closureIterSetupExc(e: ref Exception) {.compilerproc, inline.} = proc closureIterSetupExc(e: ref Exception) {.compilerproc, inline.} =
if not e.isNil: currException = e
currException = e
# some platforms have native support for stack traces: # some platforms have native support for stack traces:
const const
@ -342,12 +341,15 @@ proc raiseExceptionAux(e: ref Exception) =
if globalRaiseHook != nil: if globalRaiseHook != nil:
if not globalRaiseHook(e): return if not globalRaiseHook(e): return
when defined(cpp) and not defined(noCppExceptions): when defined(cpp) and not defined(noCppExceptions):
pushCurrentException(e) if e == currException:
raiseCounter.inc {.emit: "throw;".}
if raiseCounter == 0: else:
raiseCounter.inc # skip zero at overflow pushCurrentException(e)
e.raiseId = raiseCounter raiseCounter.inc
{.emit: "`e`->raise();".} if raiseCounter == 0:
raiseCounter.inc # skip zero at overflow
e.raiseId = raiseCounter
{.emit: "`e`->raise();".}
elif defined(nimQuirky): elif defined(nimQuirky):
pushCurrentException(e) pushCurrentException(e)
else: else:

View file

@ -5,6 +5,9 @@ bar
Need odd and >= 3 digits## Need odd and >= 3 digits##
baz baz
caught caught
--------
Triggered raises2
Raising ValueError
''' '''
""" """
@ -45,3 +48,24 @@ try:
finally: finally:
for foobar in strs: for foobar in strs:
discard discard
# issue #11118
echo "--------"
proc raises() =
raise newException(ValueError, "Raising ValueError")
proc raises2() =
try:
raises()
except ValueError as e:
echo "Triggered raises2"
raise e
try:
raises2()
except:
echo getCurrentExceptionMsg()
discard
doAssert: getCurrentException() == nil