topt_cursor2.nim 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. for c in token.children:
  20. result.add $c
  21. proc parseLeafBlockInlines(token: Token) =
  22. token.children.append(Token())
  23. token.children.append(Token()) # <-- this one AAA
  24. var emNode = newDoublyLinkedNode(Token())
  25. var i = 0
  26. var it = token.children.head
  27. while it != nil:
  28. var nxt = it.next # this is not a cursor, it takes over ownership.
  29. var childNode = it
  30. if i == 0:
  31. childNode.next = emNode # frees the object allocated in line 29 marked with AAA
  32. elif i == 1:
  33. emNode.next = childNode #
  34. it = nxt # incref on freed data, 'nxt' is freed
  35. inc i
  36. proc parse() =
  37. var token = Token()
  38. token.children.append Paragraph()
  39. parseLeafBlockInlines(token.children.head.value)
  40. for children in token.children:
  41. echo children
  42. parse()
  43. #------------------------------------------------------------------------------
  44. # issue #15629
  45. type inner = object
  46. type outer = ref inner
  47. proc `=destroy`(b: var inner) =
  48. echo "inner destroy"
  49. proc newOuter(): outer =
  50. new(result)
  51. type holder = object
  52. contents: outer
  53. proc main() =
  54. var t: holder
  55. t.contents = newOuter()
  56. main()