From b7eefc31d81eba9376144d0e4ab7cd577384a94a Mon Sep 17 00:00:00 2001 From: ringabout <43030857+ringabout@users.noreply.github.com> Date: Wed, 19 Feb 2025 00:24:41 +0800 Subject: [PATCH] implements `quirky` for functions (#24700) ref https://github.com/nim-lang/Nim/pull/24686 With this PR ```nim import std/streams proc foo() = var name = newStringStream("2r2") raise newException(ValueError, "sh") try: foo() except: discard echo 123 ``` this example no longer leaks --------- Co-authored-by: Andreas Rumpf (cherry picked from commit 510ac845188a26d4c317893ff7b260582beee54d) --- compiler/pragmas.nim | 6 +++++- lib/system/arc.nim | 5 ++++- tests/arc/tvalgrind.nim | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 tests/arc/tvalgrind.nim diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index d64e6200fd..f628afc2f0 100644 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -1295,8 +1295,12 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: var int, pragmaProposition(c, it) of wEnsures: pragmaEnsures(c, it) - of wEnforceNoRaises, wQuirky: + of wEnforceNoRaises: sym.flags.incl sfNeverRaises + of wQuirky: + sym.flags.incl sfNeverRaises + if sym.kind in {skProc, skMethod, skConverter, skFunc, skIterator}: + sym.options.incl optQuirky of wSystemRaisesDefect: sym.flags.incl sfSystemRaisesDefect of wVirtual: diff --git a/lib/system/arc.nim b/lib/system/arc.nim index 0624bd4e3a..a2c2cd7466 100644 --- a/lib/system/arc.nim +++ b/lib/system/arc.nim @@ -72,6 +72,9 @@ else: template count(x: Cell): untyped = x.rc shr rcShift +when not defined(nimHasQuirky): + {.pragma: quirky.} + proc nimNewObj(size, alignment: int): pointer {.compilerRtl.} = let hdrSize = align(sizeof(RefHeader), alignment) let s = size + hdrSize @@ -173,7 +176,7 @@ proc nimRawDispose(p: pointer, alignment: int) {.compilerRtl.} = template `=dispose`*[T](x: owned(ref T)) = nimRawDispose(cast[pointer](x), T.alignOf) #proc dispose*(x: pointer) = nimRawDispose(x) -proc nimDestroyAndDispose(p: pointer) {.compilerRtl, raises: [].} = +proc nimDestroyAndDispose(p: pointer) {.compilerRtl, quirky, raises: [].} = let rti = cast[ptr PNimTypeV2](p) if rti.destructor != nil: cast[DestructorProc](rti.destructor)(p) diff --git a/tests/arc/tvalgrind.nim b/tests/arc/tvalgrind.nim new file mode 100644 index 0000000000..27d089d153 --- /dev/null +++ b/tests/arc/tvalgrind.nim @@ -0,0 +1,16 @@ +discard """ + cmd: "nim c --mm:orc -d:useMalloc $file" + valgrind: "true" +""" + +import std/streams + + +proc foo() = + var name = newStringStream("2r2") + raise newException(ValueError, "sh") + +try: + foo() +except: + discard \ No newline at end of file