summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2024-06-10 18:43:23 +0200
committerGitHub <noreply@github.com>2024-06-10 18:43:23 +0200
commit8cbbe12ee4eaa9568d246638b1f712a5a57e20ab (patch)
treec09be0ee71cd1058f1354f8821f75987dd92f5aa
parent1cbcbd9269e19838858a9b26d455590b753b85f8 (diff)
downloadNim-8cbbe12ee4eaa9568d246638b1f712a5a57e20ab.tar.gz
fixes #22398; [backport] (#23704)
-rw-r--r--compiler/ccgstmts.nim22
-rw-r--r--tests/destructor/tgotoexc_leak.nim19
2 files changed, 32 insertions, 9 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 4f79068c5..c9783105b 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -301,13 +301,13 @@ proc genCppParamsForCtor(p: BProc; call: PNode; didGenTemp: var bool): string =
       result.add genCppInitializer(p.module, p, call[i][0].sym.typ, didGenTemp)
     else:
       #We need to test for temp in globals, see: #23657
-      let param = 
+      let param =
         if typ[i].kind in {tyVar} and call[i].kind == nkHiddenAddr:
           call[i][0]
         else:
           call[i]
-      if param.kind != nkBracketExpr or param.typ.kind in 
-        {tyRef, tyPtr, tyUncheckedArray, tyArray, tyOpenArray, 
+      if param.kind != nkBracketExpr or param.typ.kind in
+        {tyRef, tyPtr, tyUncheckedArray, tyArray, tyOpenArray,
           tyVarargs, tySequence, tyString, tyCstring, tyTuple}:
         let tempLoc = initLocExprSingleUse(p, param)
         didGenTemp = didGenTemp or tempLoc.k == locTemp
@@ -796,10 +796,14 @@ proc genRaiseStmt(p: BProc, t: PNode) =
     var e = rdLoc(a)
     discard getTypeDesc(p.module, t[0].typ)
     var typ = skipTypes(t[0].typ, abstractPtrs)
-    # XXX For reasons that currently escape me, this is only required by the new
-    # C++ based exception handling:
-    if p.config.exc == excCpp:
+    case p.config.exc
+    of excCpp:
       blockLeaveActions(p, howManyTrys = 0, howManyExcepts = p.inExceptBlockLen)
+    of excGoto:
+      blockLeaveActions(p, howManyTrys = 0,
+        howManyExcepts = (if p.nestedTryStmts.len > 0 and p.nestedTryStmts[^1].inExcept: 1 else: 0))
+    else:
+      discard
     genLineDir(p, t)
     if isImportedException(typ, p.config):
       lineF(p, cpsStmts, "throw $1;$n", [e])
@@ -1578,14 +1582,14 @@ proc genAsmStmt(p: BProc, t: PNode) =
       if whichPragma(i) == wAsmSyntax:
         asmSyntax = i[1].strVal
 
-  if asmSyntax != "" and 
+  if asmSyntax != "" and
      not (
       asmSyntax == "gcc" and hasGnuAsm in CC[p.config.cCompiler].props or
       asmSyntax == "vcc" and hasGnuAsm notin CC[p.config.cCompiler].props):
     localError(
-      p.config, t.info, 
+      p.config, t.info,
       "Your compiler does not support the specified inline assembler")
-  
+
   genAsmOrEmitStmt(p, t, isAsmStmt=true, s)
   # see bug #2362, "top level asm statements" seem to be a mis-feature
   # but even if we don't do this, the example in #2362 cannot possibly
diff --git a/tests/destructor/tgotoexc_leak.nim b/tests/destructor/tgotoexc_leak.nim
new file mode 100644
index 000000000..c8a234085
--- /dev/null
+++ b/tests/destructor/tgotoexc_leak.nim
@@ -0,0 +1,19 @@
+discard """
+  output: '''0
+true'''
+  cmd: "nim c --gc:arc $file"
+"""
+
+# bug #22398
+
+for i in 0 ..< 10_000:
+  try:
+    try:
+      raise newException(ValueError, "")
+    except CatchableError:
+      discard
+      raise newException(ValueError, "") # or raise getCurrentException(), just raise works ok
+  except ValueError:
+    discard
+echo getOccupiedMem()
+echo getCurrentException() == nil