gcleak4.nim 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. discard """
  2. outputsub: "no leak: "
  3. """
  4. type
  5. TExpr {.inheritable.} = object ## abstract base class for an expression
  6. PLiteral = ref TLiteral
  7. TLiteral = object of TExpr
  8. x: int
  9. op1: string
  10. TPlusExpr = object of TExpr
  11. a, b: ref TExpr
  12. op2: string
  13. method eval(e: ref TExpr): int {.base.} =
  14. # override this base method
  15. quit "to override!"
  16. method eval(e: ref TLiteral): int = return e.x
  17. method eval(e: ref TPlusExpr): int =
  18. # watch out: relies on dynamic binding
  19. return eval(e.a) + eval(e.b)
  20. proc newLit(x: int): ref TLiteral =
  21. new(result)
  22. result.x = x
  23. result.op1 = $getOccupiedMem()
  24. proc newPlus(a, b: sink(ref TExpr)): ref TPlusExpr =
  25. new(result)
  26. result.a = a
  27. result.b = b
  28. result.op2 = $getOccupiedMem()
  29. const Limit = when compileOption("gc", "markAndSweep") or compileOption("gc", "boehm"): 5*1024*1024 else: 500_000
  30. for i in 0..50_000:
  31. var s: array[0..11, ref TExpr]
  32. for j in 0..high(s):
  33. s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4))
  34. if eval(s[j]) != j+6:
  35. quit "error: wrong result"
  36. if getOccupiedMem() > Limit: quit("still a leak!")
  37. echo "no leak: ", getOccupiedMem()