From 065a6af2dea252818bd58af066378ee54be2c3f8 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 27 Apr 2020 22:20:14 +0200 Subject: [PATCH] fixes a critical =trace generation bug (see test case) (#14140) --- compiler/liftdestructors.nim | 6 +++++- compiler/types.nim | 2 +- tests/destructor/tcycle2.nim | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/compiler/liftdestructors.nim b/compiler/liftdestructors.nim index 61034ef033..5959e24c5e 100644 --- a/compiler/liftdestructors.nim +++ b/compiler/liftdestructors.nim @@ -253,9 +253,13 @@ proc newOpCall(op: PSym; x: PNode): PNode = proc newDeepCopyCall(op: PSym; x, y: PNode): PNode = result = newAsgnStmt(x, newOpCall(op, y)) +proc usesBuiltinArc(t: PType): bool = + proc wrap(t: PType): bool {.nimcall.} = ast.isGCedMem(t) + result = types.searchTypeFor(t, wrap) + proc useNoGc(c: TLiftCtx; t: PType): bool {.inline.} = result = optSeqDestructors in c.g.config.globalOptions and - ({tfHasGCedMem, tfHasOwned} * t.flags != {} or t.isGCedMem) + ({tfHasGCedMem, tfHasOwned} * t.flags != {} or usesBuiltinArc(t)) proc requiresDestructor(c: TLiftCtx; t: PType): bool {.inline.} = result = optSeqDestructors in c.g.config.globalOptions and diff --git a/compiler/types.nim b/compiler/types.nim index cf3f7117aa..241229df61 100644 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -253,7 +253,7 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate, else: discard -proc searchTypeFor(t: PType, predicate: TTypePredicate): bool = +proc searchTypeFor*(t: PType, predicate: TTypePredicate): bool = var marker = initIntSet() result = searchTypeForAux(t, predicate, marker) diff --git a/tests/destructor/tcycle2.nim b/tests/destructor/tcycle2.nim index 843c7cf1cd..7b03101fea 100644 --- a/tests/destructor/tcycle2.nim +++ b/tests/destructor/tcycle2.nim @@ -13,8 +13,24 @@ proc main(x: int) = let m = n n.kids.add m +type + NodeA = ref object + s: char + a: array[3, NodeA] + +proc m: NodeA = + result = NodeA(s: 'a') + result.a[0] = result + result.a[1] = result + result.a[2] = result + +proc mainA = + for i in 0..10: + discard m() + let mem = getOccupiedMem() main(90) +mainA() GC_fullCollect() echo "MEM ", getOccupiedMem() - mem