diff options
-rw-r--r-- | lib/system/arc.nim | 6 | ||||
-rw-r--r-- | tests/arc/tunref_cycle.nim | 26 |
2 files changed, 28 insertions, 4 deletions
diff --git a/lib/system/arc.nim b/lib/system/arc.nim index ed5e9f5ca..d66f4b997 100644 --- a/lib/system/arc.nim +++ b/lib/system/arc.nim @@ -207,10 +207,8 @@ proc nimDecRefIsLast(p: pointer): bool {.compilerRtl, inl.} = proc GC_unref*[T](x: ref T) = ## New runtime only supports this operation for 'ref T'. - if nimDecRefIsLast(cast[pointer](x)): - # XXX this does NOT work for virtual destructors! - `=destroy`(x[]) - nimRawDispose(cast[pointer](x), T.alignOf) + var y {.cursor.} = x + `=destroy`(y) proc GC_ref*[T](x: ref T) = ## New runtime only supports this operation for 'ref T'. diff --git a/tests/arc/tunref_cycle.nim b/tests/arc/tunref_cycle.nim new file mode 100644 index 000000000..82551b7f7 --- /dev/null +++ b/tests/arc/tunref_cycle.nim @@ -0,0 +1,26 @@ +discard """ + outputsub: '''inside closure +hello world''' + cmd: "nim c --gc:orc -d:useMalloc $file" + valgrind: true +""" + +# bug #18579 + +var fp: proc (env: pointer) {.cdecl.} +var env: pointer + +proc store(f: proc (){.closure.}) = + proc closeOver() = + echo "inside closure" + f() + (fp,env) = (cast[proc(env: pointer){.cdecl.}](rawProc closeOver), rawEnv closeOver) + GC_ref(cast[RootRef](env)) + +proc run() = + fp(env) + GC_unref(cast[RootRef](env)) + +store(proc() = echo "hello world") +run() +GC_fullCollect() |