summary refs log tree commit diff stats
path: root/tests/arc/tmovebug.nim
blob: 951979a4626fd0dc5de3c43d49e0d1cbe24429d2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
discard """
  cmd: "nim c --gc:arc $file"
  output: '''5
(w: 5)
(w: -5)
c.text = hello
c.text = hello
p.text = hello
p.toks = @["hello"]
c.text = hello
c[].text = hello
pA.text = hello
pA.toks = @["hello"]
c.text = hello
c.text = hello
pD.text = hello
pD.toks = @["hello"]
c.text = hello
c.text = hello
pOD.text = hello
pOD.toks = @["hello"]
fff
fff
2
fff
fff
2
fff
fff
2
mmm
fff
fff
fff
3
mmm
sink me (sink)
assign me (not sink)
sink me (not sink)
sinked and not optimized to a bitcopy
sinked and not optimized to a bitcopy
sinked and not optimized to a bitcopy
'''
"""

# move bug
type
  TMyObj = object
    p: pointer
    len: int

var destroyCounter = 0

proc `=destroy`(o: var TMyObj) =
  if o.p != nil:
    dealloc o.p
    o.p = nil
    inc destroyCounter

proc `=`(dst: var TMyObj, src: TMyObj) =
  `=destroy`(dst)
  dst.p = alloc(src.len)
  dst.len = src.len

proc `=sink`(dst: var TMyObj, src: TMyObj) =
  `=destroy`(dst)
  dst.p = src.p
  dst.len = src.len

type
  TObjKind = enum Z, A, B
  TCaseObj = object
    case kind: TObjKind
    of Z: discard
    of A:
      x1: int # this int plays important role
      x2: TMyObj
    of B:
      y: TMyObj

proc use(a: TCaseObj) = discard

proc moveBug(i: var int) =
  var a: array[2, TCaseObj]
  a[i] = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5))) # 1
  a[i+1] = a[i] # 2
  inc i
  use(a[i-1])

var x = 0
moveBug(x)

proc moveBug2(): (TCaseObj, TCaseObj) =
  var a: array[2, TCaseObj]
  a[0] = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5)))
  a[1] = a[0] # can move 3
  result[0] = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5))) # 4
  result[1] = result[0] # 5

proc main =
  discard moveBug2()

main()
echo destroyCounter

# bug #13314

type
  O = object
    v: int
  R = ref object
    w: int

proc `$`(r: R): string = $r[]

proc tbug13314 =
  var t5 = R(w: 5)
  var execute = proc () =
    echo t5

  execute()
  t5.w = -5
  execute()

tbug13314()

#-------------------------------------------------------------------------
# bug #13368

import strutils
proc procStat() =
  for line in @["a b", "c d", "e f"]:
    let cols = line.splitWhitespace(maxSplit=1)
    let x = cols[0]
    let (nm, rest) = (cols[0], cols[1])
procStat()


# bug #14269

import sugar, strutils

type
  Cursor = object
    text: string
  Parsed = object
    text: string
    toks: seq[string]

proc tokenize(c: var Cursor): seq[string] =
  dump c.text
  return c.text.splitWhitespace()

proc parse(): Parsed =
  var c = Cursor(text: "hello")
  dump c.text
  return Parsed(text: c.text, toks: c.tokenize) # note: c.tokenized uses c.text

let p = parse()
dump p.text
dump p.toks


proc tokenizeA(c: ptr Cursor): seq[string] =
  dump c[].text
  return c[].text.splitWhitespace()

proc parseA(): Parsed =
  var c = Cursor(text: "hello")
  dump c.text
  return Parsed(text: c.text, toks: c.addr.tokenizeA) # note: c.tokenized uses c.text

let pA = parseA()
dump pA.text
dump pA.toks


proc tokenizeD(c: Cursor): seq[string] =
  dump c.text
  return c.text.splitWhitespace()

proc parseD(): Parsed =
  var c = cast[ptr Cursor](alloc0(sizeof(Cursor)))
  c[] = Cursor(text: "hello")
  dump c.text
  return Parsed(text: c.text, toks: c[].tokenizeD) # note: c.tokenized uses c.text

let pD = parseD()
dump pD.text
dump pD.toks

# Bug would only pop up with owned refs
proc tokenizeOD(c: Cursor): seq[string] =
  dump c.text
  return c.text.splitWhitespace()

proc parseOD(): Parsed =
  var c = new Cursor
  c[] = Cursor(text: "hello")
  dump c.text
  return Parsed(text: c.text, toks: c[].tokenizeOD) # note: c.tokenized uses c.text

let pOD = parseOD()
dump pOD.text
dump pOD.toks

when false:
  # Bug would only pop up with owned refs and implicit derefs, but since they don't work together..
  {.experimental: "implicitDeref".}
  proc tokenizeOHD(c: Cursor): seq[string] =
    dump c.text
    return c.text.splitWhitespace()

  proc parseOHD(): Parsed =
    var c = new Cursor
    c[] = Cursor(text: "hello")
    dump c.text
    return Parsed(text: c.text, toks: c.tokenizeOHD) # note: c.tokenized uses c.text

  let pOHD = parseOHD()
  dump pOHD.text
  dump pOHD.toks

# bug #13456

iterator combinations[T](s: openarray[T], k: int): seq[T] =
  let n = len(s)
  assert k >= 0 and k <= n
  var pos = newSeq[int](k)
  var current = newSeq[T](k)
  for i in 0..k-1:
    pos[k-i-1] = i
  var done = false
  while not done:
    for i in 0..k-1:
      current[i] = s[pos[k-i-1]]
    yield current
    var i = 0
    while i < k:
      pos[i] += 1
      if pos[i] < n-i:
        for j in 0..i-1:
          pos[j] = pos[i] + i - j
        break
      i += 1
    if i >= k:
      break

type
  UndefEx = object of Exception

proc main2 =
  var delayedSyms = @[1, 2, 3]
  var unp: seq[int]
  block myb:
    for a in 1 .. 2:
      if delayedSyms.len > a:
        unp = delayedSyms
        for t in unp.combinations(a + 1):
          try:
            var h = false
            for k in t:
              echo "fff"
            if h: continue
            if true:
              raise newException(UndefEx, "forward declaration")
            break myb
          except UndefEx:
            echo t.len
        echo "mmm"

main2()



type ME = object
  who: string

proc `=`(x: var ME, y: ME) =
  if y.who.len > 0: echo "assign ",y.who

proc `=sink`(x: var ME, y: ME) =
  if y.who.len > 0: echo "sink ",y.who

var dump: ME
template use(x) = dump = x
template def(x) = x = dump

var c = true

proc shouldSink() =
  var x = ME(who: "me (sink)")
  use(x) # we analyse this
  if c: def(x)
  else: def(x)
  use(x) # ok, with the [else] part.

shouldSink()

dump = ME()

proc shouldNotSink() =
  var x = ME(who: "me (not sink)")
  use(x) # we analyse this
  if c: def(x)
  use(x) # Not ok without the '[else]'

shouldNotSink()

# bug #14568
import os

type O2 = object
  s: seq[int]

proc `=sink`(dest: var O2, src: O2) =
  echo "sinked and not optimized to a bitcopy"

var testSeq: O2

proc Update(): void =
  # testSeq.add(0) # uncommenting this line fixes the leak
  testSeq = O2(s: @[])
  testSeq.s.add(0)

for i in 1..3:
  Update()