taddr.nim 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. discard """
  2. targets: "c cpp js"
  3. matrix: "; -d:release"
  4. """
  5. type T = object
  6. x: int
  7. s: string
  8. var obj: T
  9. var fieldAddr = addr(obj.x)
  10. var objAddr = addr(obj)
  11. # Integer tests
  12. var field = fieldAddr[]
  13. doAssert field == 0
  14. var objDeref = objAddr[]
  15. doAssert objDeref.x == 0
  16. # Change value
  17. obj.x = 42
  18. doAssert field == 0
  19. doAssert objDeref.x == 0
  20. field = fieldAddr[]
  21. objDeref = objAddr[]
  22. doAssert field == 42
  23. doAssert objDeref.x == 42
  24. # String tests
  25. obj.s = "lorem ipsum dolor sit amet"
  26. var indexAddr = addr(obj.s[2])
  27. doAssert indexAddr[] == 'r'
  28. indexAddr[] = 'd'
  29. doAssert indexAddr[] == 'd'
  30. doAssert obj.s == "lodem ipsum dolor sit amet"
  31. # Bug #2148
  32. var x: array[2, int]
  33. var y = addr x[1]
  34. y[] = 12
  35. doAssert(x[1] == 12)
  36. type
  37. Foo = object
  38. bar: int
  39. var foo: array[2, Foo]
  40. var z = addr foo[1]
  41. z[].bar = 12345
  42. doAssert(foo[1].bar == 12345)
  43. var t : tuple[a, b: int]
  44. var pt = addr t[1]
  45. pt[] = 123
  46. doAssert(t.b == 123)
  47. #block: # Test "untyped" pointer.
  48. proc testPtr(p: pointer, a: int) =
  49. doAssert(a == 5)
  50. (cast[ptr int](p))[] = 124
  51. var i = 123
  52. testPtr(addr i, 5)
  53. doAssert(i == 124)
  54. var someGlobal = 5
  55. proc getSomeGlobalPtr(): ptr int = addr someGlobal
  56. let someGlobalPtr = getSomeGlobalPtr()
  57. doAssert(someGlobalPtr[] == 5)
  58. someGlobalPtr[] = 10
  59. doAssert(someGlobal == 10)
  60. block:
  61. # bug #14576
  62. # lots of these used to give: Error: internal error: genAddr: 2
  63. proc byLent[T](a: T): lent T = a
  64. proc byPtr[T](a: T): ptr T = a.unsafeAddr
  65. block:
  66. let a = (10,11)
  67. let (x,y) = byLent(a)
  68. doAssert (x,y) == a
  69. block: # (with -d:release) bug #14578
  70. let a = 10
  71. doAssert byLent(a) == 10
  72. let a2 = byLent(a)
  73. doAssert a2 == 10
  74. block:
  75. let a = [11,12]
  76. doAssert byLent(a) == [11,12] # bug #15958
  77. let a2 = (11,)
  78. doAssert byLent(a2) == (11,)
  79. block:
  80. proc byLent2[T](a: seq[T]): lent T = a[1]
  81. var a = @[20,21,22]
  82. doAssert byLent2(a) == 21
  83. block: # sanity checks
  84. proc bar[T](a: var T): var T = a
  85. var a = (10, 11)
  86. let (k,v) = bar(a)
  87. doAssert (k, v) == a
  88. doAssert k == 10
  89. bar(a)[0]+=100
  90. doAssert a == (110, 11)
  91. var a2 = 12
  92. doAssert bar(a2) == a2
  93. bar(a2).inc
  94. doAssert a2 == 13
  95. block: # pending bug #15959
  96. when false:
  97. proc byLent2[T](a: T): lent type(a[0]) = a[0]
  98. proc test14420() = # bug #14420
  99. # s/proc/template/ would hit bug #16005
  100. block:
  101. type Foo = object
  102. x: float
  103. proc fn(a: var Foo): var float =
  104. ## WAS: discard <- turn this into a comment (or a `discard`) and error disappears
  105. # result = a.x # this works
  106. a.x # WAS: Error: limited VM support for 'addr'
  107. proc fn2(a: var Foo): var float =
  108. result = a.x # this works
  109. a.x # WAS: Error: limited VM support for 'addr'
  110. var a = Foo()
  111. discard fn(a)
  112. discard fn2(a)
  113. block:
  114. proc byLent2[T](a: T): lent T =
  115. runnableExamples: discard
  116. a
  117. proc byLent3[T](a: T): lent T =
  118. runnableExamples: discard
  119. result = a
  120. var a = 10
  121. let x3 = byLent3(a) # works
  122. let x2 = byLent2(a) # WAS: Error: internal error: genAddr: nkStmtListExpr
  123. block:
  124. type MyOption[T] = object
  125. case has: bool
  126. of true:
  127. value: T
  128. of false:
  129. discard
  130. func some[T](val: T): MyOption[T] =
  131. result = MyOption[T](has: true, value: val)
  132. func get[T](opt: MyOption[T]): lent T =
  133. doAssert opt.has
  134. # result = opt.value # this was ok
  135. opt.value # this had the bug
  136. let x = some(10)
  137. doAssert x.get() == 10
  138. template test14339() = # bug #14339
  139. block:
  140. type
  141. Node = ref object
  142. val: int
  143. proc bar(c: Node): var int =
  144. var n = c # was: Error: limited VM support for 'addr'
  145. c.val
  146. var a = Node()
  147. discard a.bar()
  148. block:
  149. type
  150. Node = ref object
  151. val: int
  152. proc bar(c: Node): var int =
  153. var n = c
  154. doAssert n.val == n[].val
  155. n.val
  156. var a = Node(val: 3)
  157. a.bar() = 5
  158. when nimvm:
  159. doAssert a.val == 5
  160. else:
  161. when not defined(js): # pending bug #16003
  162. doAssert a.val == 5
  163. template main =
  164. # xxx wrap all other tests here like that so they're also tested in VM
  165. test14420()
  166. test14339()
  167. static: main()
  168. main()