summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/closureiters.nim11
-rw-r--r--lib/system/excpt.nim18
-rw-r--r--tests/cpp/tcppraise.nim24
3 files changed, 39 insertions, 14 deletions
diff --git a/compiler/closureiters.nim b/compiler/closureiters.nim
index c60ce96a2..c140b5464 100644
--- a/compiler/closureiters.nim
+++ b/compiler/closureiters.nim
@@ -90,9 +90,6 @@
 #  :unrollFinally = true
 #  goto nearestFinally (or -1 if not exists)
 #
-# Every finally block calls closureIterEndFinally() upon its successful
-# completion.
-#
 # Example:
 #
 # try:
@@ -126,6 +123,7 @@
 #     if :curExc.isNil:
 #       return :tmpResult
 #     else:
+#       closureIterSetupExc(nil)
 #       raise
 #   state = -1 # Goto next state. In this case we just exit
 #   break :stateLoop
@@ -809,10 +807,11 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
   let retStmt = newTree(nkReturnStmt, asgn)
   let branch = newTree(nkElifBranch, cmp, retStmt)
 
-  # The C++ backend requires `getCurrentException` here.
-  let raiseStmt = newTree(nkRaiseStmt, ctx.g.callCodegenProc("getCurrentException"))
+  let nullifyExc = newTree(nkCall, newSymNode(ctx.g.getCompilerProc("closureIterSetupExc")), nilnode)
+  nullifyExc.info = info
+  let raiseStmt = newTree(nkRaiseStmt, curExc)
   raiseStmt.info = info
-  let elseBranch = newTree(nkElse, raiseStmt)
+  let elseBranch = newTree(nkElse, newTree(nkStmtList, nullifyExc, raiseStmt))
 
   let ifBody = newTree(nkIfStmt, branch, elseBranch)
   let elifBranch = newTree(nkElifBranch, ctx.newUnrollFinallyAccess(info), ifBody)
diff --git a/lib/system/excpt.nim b/lib/system/excpt.nim
index 2a925fd29..0898ad0fd 100644
--- a/lib/system/excpt.nim
+++ b/lib/system/excpt.nim
@@ -136,8 +136,7 @@ proc popCurrentExceptionEx(id: uint) {.compilerRtl.} =
     prev.up = cur.up
 
 proc closureIterSetupExc(e: ref Exception) {.compilerproc, inline.} =
-  if not e.isNil:
-    currException = e
+  currException = e
 
 # some platforms have native support for stack traces:
 const
@@ -342,12 +341,15 @@ proc raiseExceptionAux(e: ref Exception) =
   if globalRaiseHook != nil:
     if not globalRaiseHook(e): return
   when defined(cpp) and not defined(noCppExceptions):
-    pushCurrentException(e)
-    raiseCounter.inc
-    if raiseCounter == 0:
-      raiseCounter.inc # skip zero at overflow
-    e.raiseId = raiseCounter
-    {.emit: "`e`->raise();".}
+    if e == currException:
+      {.emit: "throw;".}
+    else:
+      pushCurrentException(e)
+      raiseCounter.inc
+      if raiseCounter == 0:
+        raiseCounter.inc # skip zero at overflow
+      e.raiseId = raiseCounter
+      {.emit: "`e`->raise();".}
   elif defined(nimQuirky):
     pushCurrentException(e)
   else:
diff --git a/tests/cpp/tcppraise.nim b/tests/cpp/tcppraise.nim
index 84cacf7f0..8f34cb3e4 100644
--- a/tests/cpp/tcppraise.nim
+++ b/tests/cpp/tcppraise.nim
@@ -5,6 +5,9 @@ bar
 Need odd and >= 3 digits##
 baz
 caught
+--------
+Triggered raises2
+Raising ValueError
 '''
 """
 
@@ -45,3 +48,24 @@ try:
 finally:
   for foobar in strs:
     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
\ No newline at end of file