From 714fd811996515539eb0efd7b6f7543a73025e18 Mon Sep 17 00:00:00 2001 From: narimiran Date: Thu, 15 Oct 2020 14:00:15 +0200 Subject: [PATCH] remove tests that shouldn't have been backported in previous commit --- tests/arc/tcaseobjcopy.nim | 246 --------------- tests/arc/tcomputedgotocopy.nim | 41 --- tests/arc/tmovebugcopy.nim | 526 -------------------------------- tests/arc/tweavecopy.nim | 154 ---------- 4 files changed, 967 deletions(-) delete mode 100644 tests/arc/tcaseobjcopy.nim delete mode 100644 tests/arc/tcomputedgotocopy.nim delete mode 100644 tests/arc/tmovebugcopy.nim delete mode 100644 tests/arc/tweavecopy.nim diff --git a/tests/arc/tcaseobjcopy.nim b/tests/arc/tcaseobjcopy.nim deleted file mode 100644 index ed07b404e9..0000000000 --- a/tests/arc/tcaseobjcopy.nim +++ /dev/null @@ -1,246 +0,0 @@ -discard """ - valgrind: true - cmd: "nim c --gc:arc -d:useMalloc $file" - output: '''myobj destroyed -myobj destroyed -myobj destroyed -A -B -begin -end -prevented -(ok: true, value: "ok") -myobj destroyed -''' -""" - -# bug #13102 - -type - D = ref object - R = object - case o: bool - of false: - discard - of true: - field: D - -iterator things(): R = - when true: - var - unit = D() - while true: - yield R(o: true, field: unit) - else: - while true: - var - unit = D() - yield R(o: true, field: unit) - -proc main = - var i = 0 - for item in things(): - discard item.field - inc i - if i == 2: break - -main() - -# bug #13149 - -type - TMyObj = object - p: pointer - len: int - -proc `=destroy`(o: var TMyObj) = - if o.p != nil: - dealloc o.p - o.p = nil - echo "myobj destroyed" - -proc `=copy`(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 testSinks: TCaseObj = - result = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5))) - result = TCaseObj(kind: B, y: TMyObj(len: 3, p: alloc(3))) - -proc use(x: TCaseObj) = discard - -proc testCopies(i: int) = - var a: array[2, TCaseObj] - a[i] = TCaseObj(kind: A, x1: 5000, x2: TMyObj(len: 5, p: alloc(5))) - a[i+1] = a[i] # copy, cannot move - use(a[i]) - -let x1 = testSinks() -testCopies(0) - -# bug #12957 - -type - PegKind* = enum - pkCharChoice, - pkSequence - Peg* = object ## type that represents a PEG - case kind: PegKind - of pkCharChoice: charChoice: ref set[char] - else: discard - sons: seq[Peg] - -proc charSet*(s: set[char]): Peg = - ## constructs a PEG from a character set `s` - result = Peg(kind: pkCharChoice) - new(result.charChoice) - result.charChoice[] = s - -proc len(a: Peg): int {.inline.} = return a.sons.len -proc myadd(d: var Peg, s: Peg) {.inline.} = add(d.sons, s) - -proc sequence*(a: openArray[Peg]): Peg = - result = Peg(kind: pkSequence, sons: @[]) - when false: - #works too: - result.myadd(a[0]) - result.myadd(a[1]) - for x in items(a): - # works: - #result.sons.add(x) - # fails: - result.myadd x - if result.len == 1: - result = result.sons[0] # this must not move! - -when true: - # bug #12957 - - proc p = - echo "A" - let x = sequence([charSet({'a'..'z', 'A'..'Z', '_'}), - charSet({'a'..'z', 'A'..'Z', '0'..'9', '_'})]) - echo "B" - p() - - proc testSubObjAssignment = - echo "begin" - # There must be extactly one element in the array constructor! - let x = sequence([charSet({'a'..'z', 'A'..'Z', '_'})]) - echo "end" - testSubObjAssignment() - - -#------------------------------------------------ - -type - MyObject = object - x1: string - case kind1: bool - of false: y1: string - of true: - y2: seq[string] - case kind2: bool - of true: z1: string - of false: - z2: seq[string] - flag: bool - x2: string - -proc test_myobject = - var x: MyObject - x.x1 = "x1" - x.x2 = "x2" - x.y1 = "ljhkjhkjh" - x.kind1 = true - x.y2 = @["1", "2"] - x.kind2 = true - x.z1 = "yes" - x.kind2 = false - x.z2 = @["1", "2"] - x.kind2 = true - x.z1 = "yes" - x.kind2 = true # should be no effect - doAssert(x.z1 == "yes") - x.kind2 = false - x.kind1 = x.kind2 # support self assignment with effect - - try: - x.kind1 = x.flag # flag is not accesible - except FieldDefect: - echo "prevented" - - doAssert(x.x1 == "x1") - doAssert(x.x2 == "x2") - - -test_myobject() - - -#------------------------------------------------ -# bug #14244 - -type - RocksDBResult*[T] = object - case ok*: bool - of true: - value*: T - else: - error*: string - -proc init(): RocksDBResult[string] = - result.ok = true - result.value = "ok" - -echo init() - - -#------------------------------------------------ -# bug #14312 - -type MyObj = object - case kind: bool - of false: x0: int # would work with a type like seq[int]; value would be reset - of true: x1: string - -var a = MyObj(kind: false, x0: 1234) -a.kind = true -doAssert(a.x1 == "") - -block: - # bug #15532 - type Kind = enum - k0, k1 - - type Foo = object - y: int - case kind: Kind - of k0: x0: int - of k1: x1: int - - const j0 = Foo(y: 1, kind: k0, x0: 2) - const j1 = Foo(y: 1, kind: k1, x1: 2) - - doAssert j0.y == 1 - doAssert j0.kind == k0 - doAssert j1.kind == k1 - - doAssert j1.x1 == 2 - doAssert j0.x0 == 2 diff --git a/tests/arc/tcomputedgotocopy.nim b/tests/arc/tcomputedgotocopy.nim deleted file mode 100644 index 78cb6c5c00..0000000000 --- a/tests/arc/tcomputedgotocopy.nim +++ /dev/null @@ -1,41 +0,0 @@ -discard """ - cmd: '''nim c --newruntime $file''' - output: '''2 -2''' -""" - -type - ObjWithDestructor = object - a: int -proc `=destroy`(self: var ObjWithDestructor) = - echo "destroyed" - -proc `=copy`(self: var ObjWithDestructor, other: ObjWithDestructor) = - echo "copied" - -proc test(a: range[0..1], arg: ObjWithDestructor) = - var iteration = 0 - while true: - {.computedGoto.} - - let - b = int(a) * 2 - c = a - d = arg - e = arg - - discard c - discard d - discard e - - inc iteration - - case a - of 0: - assert false - of 1: - echo b - if iteration == 2: - break - -test(1, ObjWithDestructor()) diff --git a/tests/arc/tmovebugcopy.nim b/tests/arc/tmovebugcopy.nim deleted file mode 100644 index 7c52281477..0000000000 --- a/tests/arc/tmovebugcopy.nim +++ /dev/null @@ -1,526 +0,0 @@ -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 -(data: @[0, 0]) -(data: @[0, 0]) -(data: @[0, 0]) -(data: @[0, 0]) -(data: @[0, 0]) -(data: @[0, 0]) -(data: @[0, 0]) -100 -hey -hey -(a: "a", b: 2) -ho -(a: "b", b: 3) -(b: "b", a: 2) -ho -(b: "a", a: 3) -hey -break -break -hey -ho -hey -ho -ho -king -live long; long live -king -hi -try -bye -''' -""" - -# 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 `=copy`(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 ValueError - -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 `=copy`(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() = - # testSeq.add(0) # uncommenting this line fixes the leak - testSeq = O2(s: @[]) - testSeq.s.add(0) - -for i in 1..3: - update() - - -# bug #14961 -type - Foo = object - data: seq[int] - -proc initFoo(len: int): Foo = - result = (let s = newSeq[int](len); Foo(data: s) ) - -var f = initFoo(2) -echo initFoo(2) - -proc initFoo2(len: int) = - echo if true: - let s = newSeq[int](len); Foo(data: s) - else: - let s = newSeq[int](len); Foo(data: s) - -initFoo2(2) - -proc initFoo3(len: int) = - echo (block: - let s = newSeq[int](len); Foo(data: s)) - -initFoo3(2) - -proc initFoo4(len: int) = - echo (let s = newSeq[int](len); Foo(data: s)) - -initFoo4(2) - -proc initFoo5(len: int) = - echo (case true - of true: - let s = newSeq[int](len); Foo(data: s) - of false: - let s = newSeq[int](len); Foo(data: s)) - -initFoo5(2) - -proc initFoo6(len: int) = - echo (block: - try: - let s = newSeq[int](len); Foo(data: s) - finally: discard) - -initFoo6(2) - -proc initFoo7(len: int) = - echo (block: - try: - raise newException(CatchableError, "sup") - let s = newSeq[int](len); Foo(data: s) - except CatchableError: - let s = newSeq[int](len); Foo(data: s) ) - -initFoo7(2) - - -# bug #14902 -iterator zip[T](s: openarray[T]): (T, T) = - var i = 0 - while i < 10: - yield (s[i mod 2], s[i mod 2 + 1]) - inc i - -var lastMem = int.high - -proc leak = - const len = 10 - var x = @[newString(len), newString(len), newString(len)] - - var c = 0 - for (a, b) in zip(x): - let newMem = getOccupiedMem() - assert newMem <= lastMem - lastMem = newMem - c += a.len - echo c - -leak() - - -proc consume(a: sink string) = echo a - -proc weirdScopes = - if (let a = "hey"; a.len > 0): - echo a - - while (let a = "hey"; a.len > 0): - echo a - break - - var a = block: (a: "a", b: 2) - echo a - (discard; a) = (echo "ho"; (a: "b", b: 3)) - echo a - - var b = try: (b: "b", a: 2) - except: raise - echo b - (discard; b) = (echo "ho"; (b: "a", a: 3)) - echo b - - var s = "break" - consume((echo "hey"; s)) - echo s - - echo (block: - var a = "hey" - (echo "hey"; "ho")) - - var b2 = "ho" - echo (block: - var a = "hey" - (echo "hey"; b2)) - echo b2 - - type status = enum - alive - - var king = "king" - echo (block: - var a = "a" - when true: - var b = "b" - case alive - of alive: - try: - var c = "c" - if true: - king - else: - "the abyss" - except: - echo "he ded" - "dead king") - echo "live long; long live" - echo king - -weirdScopes() - - -# bug #14985 -proc getScope(): string = - if true: - "hi" - else: - "else" - -echo getScope() - -proc getScope3(): string = - try: - "try" - except: - "except" - -echo getScope3() - -proc getScope2(): string = - case true - of true: - "bye" - else: - "else" - -echo getScope2() diff --git a/tests/arc/tweavecopy.nim b/tests/arc/tweavecopy.nim deleted file mode 100644 index fc796b3525..0000000000 --- a/tests/arc/tweavecopy.nim +++ /dev/null @@ -1,154 +0,0 @@ -discard """ - outputsub: '''Success''' - cmd: '''nim c --gc:arc --threads:on $file''' - disabled: "bsd" -""" - -# bug #13936 - -import std/atomics - -const MemBlockSize = 256 - -type - ChannelSPSCSingle* = object - full{.align: 128.}: Atomic[bool] - itemSize*: uint8 - buffer*{.align: 8.}: UncheckedArray[byte] - -proc `=copy`( - dest: var ChannelSPSCSingle, - source: ChannelSPSCSingle - ) {.error: "A channel cannot be copied".} - -proc initialize*(chan: var ChannelSPSCSingle, itemsize: SomeInteger) {.inline.} = - ## If ChannelSPSCSingle is used intrusive another data structure - ## be aware that it should be the last part due to ending by UncheckedArray - ## Also due to 128 bytes padding, it automatically takes half - ## of the default MemBlockSize - assert itemsize.int in 0 .. int high(uint8) - assert itemSize.int + - sizeof(chan.itemsize) + - sizeof(chan.full) < MemBlockSize - - chan.itemSize = uint8 itemsize - chan.full.store(false, moRelaxed) - -func isEmpty*(chan: var ChannelSPSCSingle): bool {.inline.} = - not chan.full.load(moAcquire) - -func tryRecv*[T](chan: var ChannelSPSCSingle, dst: var T): bool {.inline.} = - ## Try receiving the item buffered in the channel - ## Returns true if successful (channel was not empty) - ## - ## ⚠ Use only in the consumer thread that reads from the channel. - assert (sizeof(T) == chan.itemsize.int) or - # Support dummy object - (sizeof(T) == 0 and chan.itemsize == 1) - - let full = chan.full.load(moAcquire) - if not full: - return false - dst = cast[ptr T](chan.buffer.addr)[] - chan.full.store(false, moRelease) - return true - -func trySend*[T](chan: var ChannelSPSCSingle, src: sink T): bool {.inline.} = - ## Try sending an item into the channel - ## Reurns true if successful (channel was empty) - ## - ## ⚠ Use only in the producer thread that writes from the channel. - assert (sizeof(T) == chan.itemsize.int) or - # Support dummy object - (sizeof(T) == 0 and chan.itemsize == 1) - - let full = chan.full.load(moAcquire) - if full: - return false - cast[ptr T](chan.buffer.addr)[] = src - chan.full.store(true, moRelease) - return true - -# Sanity checks -# ------------------------------------------------------------------------------ -when isMainModule: - - when not compileOption("threads"): - {.error: "This requires --threads:on compilation flag".} - - template sendLoop[T](chan: var ChannelSPSCSingle, - data: sink T, - body: untyped): untyped = - while not chan.trySend(data): - body - - template recvLoop[T](chan: var ChannelSPSCSingle, - data: var T, - body: untyped): untyped = - while not chan.tryRecv(data): - body - - type - ThreadArgs = object - ID: WorkerKind - chan: ptr ChannelSPSCSingle - - WorkerKind = enum - Sender - Receiver - - template Worker(id: WorkerKind, body: untyped): untyped {.dirty.} = - if args.ID == id: - body - - proc thread_func(args: ThreadArgs) = - - # Worker RECEIVER: - # --------- - # <- chan - # <- chan - # <- chan - # - # Worker SENDER: - # --------- - # chan <- 42 - # chan <- 53 - # chan <- 64 - Worker(Receiver): - var val: int - for j in 0 ..< 10: - args.chan[].recvLoop(val): - # Busy loop, in prod we might want to yield the core/thread timeslice - discard - echo " Receiver got: ", val - doAssert val == 42 + j*11 - - Worker(Sender): - doAssert args.chan.full.load(moRelaxed) == false - for j in 0 ..< 10: - let val = 42 + j*11 - args.chan[].sendLoop(val): - # Busy loop, in prod we might want to yield the core/thread timeslice - discard - echo "Sender sent: ", val - - proc main() = - echo "Testing if 2 threads can send data" - echo "-----------------------------------" - var threads: array[2, Thread[ThreadArgs]] - - var chan = cast[ptr ChannelSPSCSingle](allocShared(MemBlockSize)) - chan[].initialize(itemSize = sizeof(int)) - - createThread(threads[0], thread_func, ThreadArgs(ID: Receiver, chan: chan)) - createThread(threads[1], thread_func, ThreadArgs(ID: Sender, chan: chan)) - - joinThread(threads[0]) - joinThread(threads[1]) - - freeShared(chan) - - echo "-----------------------------------" - echo "Success" - - main()