taddr.nim 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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 testStatic15464() = # bug #15464
  164. proc access(s: var seq[char], i: int): var char = s[i]
  165. proc access(s: var string, i: int): var char = s[i]
  166. static:
  167. var s = @['a', 'b', 'c']
  168. access(s, 2) = 'C'
  169. doAssert access(s, 2) == 'C'
  170. static:
  171. var s = "abc"
  172. access(s, 2) = 'C'
  173. doAssert access(s, 2) == 'C'
  174. proc test15464() = # bug #15464 (v2)
  175. proc access(s: var seq[char], i: int): var char = s[i]
  176. proc access(s: var string, i: int): var char = s[i]
  177. block:
  178. var s = @['a', 'b', 'c']
  179. access(s, 2) = 'C'
  180. doAssert access(s, 2) == 'C'
  181. block:
  182. var s = "abc"
  183. access(s, 2) = 'C'
  184. doAssert access(s, 2) == 'C'
  185. block: # bug #15939
  186. block:
  187. const foo = "foo"
  188. proc proc1(s: var string) =
  189. if s[^1] notin {'a'..'z'}:
  190. s = ""
  191. proc proc2(f: string): string =
  192. result = f
  193. proc1(result)
  194. const bar = proc2(foo)
  195. doAssert bar == "foo"
  196. proc test15939() = # bug #15939 (v2)
  197. template fn(a) =
  198. let pa = a[0].addr
  199. doAssert pa != nil
  200. doAssert pa[] == 'a'
  201. pa[] = 'x'
  202. doAssert pa[] == 'x'
  203. doAssert a == "xbc"
  204. when not defined js: # otherwise overflows
  205. let pa2 = cast[ptr char](cast[int](pa) + 1)
  206. doAssert pa2[] == 'b'
  207. pa2[] = 'B'
  208. doAssert a == "xBc"
  209. # mystring[ind].addr
  210. var a = "abc"
  211. fn(a)
  212. # mycstring[ind].addr
  213. template cstringTest =
  214. var a2 = "abc"
  215. var b2 = a2.cstring
  216. fn(b2)
  217. when nimvm: cstringTest()
  218. else: # can't take address of cstring element in js
  219. when not defined(js): cstringTest()
  220. template main =
  221. # xxx wrap all other tests here like that so they're also tested in VM
  222. test14420()
  223. test14339()
  224. test15464()
  225. test15939()
  226. testStatic15464()
  227. static: main()
  228. main()