topt_cursor2.nim 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. discard """
  2. cmd: '''nim c --gc:arc $file'''
  3. output: '''emptyemptyempty
  4. inner destroy
  5. '''
  6. """
  7. # bug #15039
  8. import lists
  9. type
  10. Token = ref object of RootObj
  11. children: DoublyLinkedList[Token]
  12. Paragraph = ref object of Token
  13. method `$`(token: Token): string {.base.} =
  14. result = "empty"
  15. method `$`(token: Paragraph): string =
  16. if token.children.head == nil:
  17. result = ""
  18. else:
  19. result = ""
  20. for c in token.children:
  21. result.add $c
  22. proc parseLeafBlockInlines(token: Token) =
  23. token.children.append(Token())
  24. token.children.append(Token()) # <-- this one AAA
  25. var emNode = newDoublyLinkedNode(Token())
  26. var i = 0
  27. var it = token.children.head
  28. while it != nil:
  29. var nxt = it.next # this is not a cursor, it takes over ownership.
  30. var childNode = it
  31. if i == 0:
  32. childNode.next = emNode # frees the object allocated in line 29 marked with AAA
  33. elif i == 1:
  34. emNode.next = childNode #
  35. it = nxt # incref on freed data, 'nxt' is freed
  36. inc i
  37. proc parse() =
  38. var token = Token()
  39. token.children.append Paragraph()
  40. parseLeafBlockInlines(token.children.head.value)
  41. for children in token.children:
  42. echo children
  43. parse()
  44. #------------------------------------------------------------------------------
  45. # issue #15629
  46. type inner = object
  47. type outer = ref inner
  48. proc `=destroy`(b: var inner) =
  49. echo "inner destroy"
  50. proc newOuter(): outer =
  51. new(result)
  52. type holder = object
  53. contents: outer
  54. proc main() =
  55. var t: holder = holder()
  56. t.contents = newOuter()
  57. main()