From 451b59e5e184ac80bd113fc9a903ec27ee42a008 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sun, 1 Dec 2019 07:22:12 +0100 Subject: [PATCH] closes #12758 --- tests/destructor/tgcleak4.nim | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 tests/destructor/tgcleak4.nim diff --git a/tests/destructor/tgcleak4.nim b/tests/destructor/tgcleak4.nim new file mode 100644 index 0000000000000..4299c8841b9de --- /dev/null +++ b/tests/destructor/tgcleak4.nim @@ -0,0 +1,47 @@ +discard """ + outputsub: "no leak: " + cmd: "nim c --gc:arc $file" +""" +# bug #12758 +type + TExpr {.inheritable.} = object ## abstract base class for an expression + PLiteral = ref TLiteral + TLiteral = object of TExpr + x: int + op1: string + TPlusExpr = object of TExpr + a, b: ref TExpr + op2: string + +method eval(e: ref TExpr): int {.base.} = + # override this base method + quit "to override!" + +method eval(e: ref TLiteral): int = return e.x + +method eval(e: ref TPlusExpr): int = + # watch out: relies on dynamic binding + return eval(e.a) + eval(e.b) + +proc newLit(x: int): ref TLiteral = + new(result) + result.x = x + result.op1 = $getOccupiedMem() + +proc newPlus(a, b: ref TExpr): ref TPlusExpr = + new(result) + result.a = a + result.b = b + result.op2 = $getOccupiedMem() + +const Limit = when compileOption("gc", "markAndSweep") or compileOption("gc", "boehm"): 5*1024*1024 else: 500_000 + +for i in 0..100_000: + var s: array[0..11, ref TExpr] + for j in 0..high(s): + s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4)) + if eval(s[j]) != j+6: + quit "error: wrong result" + if getOccupiedMem() > Limit: quit("still a leak!") + +echo "no leak: ", getOccupiedMem()