diff options
Diffstat (limited to 'tests/ccgbugs')
104 files changed, 2826 insertions, 0 deletions
diff --git a/tests/ccgbugs/m1/defs.nim b/tests/ccgbugs/m1/defs.nim new file mode 100644 index 000000000..ed78d8b72 --- /dev/null +++ b/tests/ccgbugs/m1/defs.nim @@ -0,0 +1,4 @@ +type MyObj* = object + field1*: int + s*: string + ch*: char diff --git a/tests/ccgbugs/m19445.c b/tests/ccgbugs/m19445.c new file mode 100644 index 000000000..74c23d4b4 --- /dev/null +++ b/tests/ccgbugs/m19445.c @@ -0,0 +1,3 @@ +#include "m19445.h" + +const Foo f = {10, 20, 30, 40}; \ No newline at end of file diff --git a/tests/ccgbugs/m2/defs.nim b/tests/ccgbugs/m2/defs.nim new file mode 100644 index 000000000..798d1fea8 --- /dev/null +++ b/tests/ccgbugs/m2/defs.nim @@ -0,0 +1,4 @@ +type MyObj* = object + s*: string + field1*: int + ch*: char diff --git a/tests/ccgbugs/mstatic_assert.nim b/tests/ccgbugs/mstatic_assert.nim new file mode 100644 index 000000000..dbf9c03d1 --- /dev/null +++ b/tests/ccgbugs/mstatic_assert.nim @@ -0,0 +1,6 @@ +{.emit:""" +NIM_STATIC_ASSERT(sizeof(bool) == 1, ""); +#warning "foo2" +NIM_STATIC_ASSERT(sizeof(bool) == 2, ""); +#warning "foo3" +""".} diff --git a/tests/ccgbugs/mymodule.nim b/tests/ccgbugs/mymodule.nim new file mode 100644 index 000000000..8c78cdf9b --- /dev/null +++ b/tests/ccgbugs/mymodule.nim @@ -0,0 +1,14 @@ +type + MyRefObject* = ref object + s: string + + BaseObj* = ref object of RootObj + ChildObj* = ref object of BaseObj + +proc newMyRefObject*(s: string): MyRefObject = + new(result) + result.s = s + +proc `$`*(o: MyRefObject): string = + o.s + \ No newline at end of file diff --git a/tests/ccgbugs/pkg8616/rtarray.nim b/tests/ccgbugs/pkg8616/rtarray.nim new file mode 100644 index 000000000..286dbb8cd --- /dev/null +++ b/tests/ccgbugs/pkg8616/rtarray.nim @@ -0,0 +1,2 @@ +proc head*[T](pp: var array[1,T]): var T = + result = pp[0] diff --git a/tests/ccgbugs/pkg8616/scheduler.nim b/tests/ccgbugs/pkg8616/scheduler.nim new file mode 100644 index 000000000..0730000c4 --- /dev/null +++ b/tests/ccgbugs/pkg8616/scheduler.nim @@ -0,0 +1,10 @@ +import rtarray + +type + T = tuple[x:int] + +var + arr: array[1,T] + +proc init*() = + discard head(arr) diff --git a/tests/ccgbugs/t10128.nim b/tests/ccgbugs/t10128.nim new file mode 100644 index 000000000..48970916f --- /dev/null +++ b/tests/ccgbugs/t10128.nim @@ -0,0 +1,18 @@ +# bug #10128 +let data = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" +var seq2 = newSeq[char](data.len) +for i in 0..<data.len: + seq2[i] = data[i] + +let c = '\128' + +# case 1 +doAssert data[c.int] == 'y' +doAssert seq2[c.int] == 'y' + +proc play(x: openArray[char]) = + doAssert x[c.int] == 'y' + +# case2 +play(data) +play(seq2) \ No newline at end of file diff --git a/tests/ccgbugs/t10964.nim b/tests/ccgbugs/t10964.nim new file mode 100644 index 000000000..c19db6997 --- /dev/null +++ b/tests/ccgbugs/t10964.nim @@ -0,0 +1,7 @@ +func test*(input: var openArray[int32], start: int = 0, fin: int = input.len - 1) = + discard + +var someSeq = @[1'i32] + +test(someSeq) +# bug with gcc 14 \ No newline at end of file diff --git a/tests/ccgbugs/t13062.nim b/tests/ccgbugs/t13062.nim new file mode 100644 index 000000000..cfda1da7c --- /dev/null +++ b/tests/ccgbugs/t13062.nim @@ -0,0 +1,33 @@ +discard """ + matrix: "--mm:refc; --mm:orc" + targets: "c cpp" +""" + +import atomics + +type + Pledge* {.exportc.} = object + p: PledgePtr + + PledgeKind {.exportc.} = enum + Single + Iteration + + PledgePtr {.exportc.} = ptr object + case kind: PledgeKind + of Single: + impl: PledgeImpl + of Iteration: + discard + + PledgeImpl {.exportc.} = object + fulfilled: Atomic[bool] + +var x: Pledge +when defined(cpp): + # TODO: fixme + discard "it doesn't work for refc/orc because of contrived `Atomic` in cpp" +elif defined(gcRefc): + doAssert x.repr == "[p = nil]" +else: # fixme # bug #20081 + doAssert x.repr == "Pledge(p: nil)" diff --git a/tests/ccgbugs/t13902.nim b/tests/ccgbugs/t13902.nim new file mode 100644 index 000000000..fd4f76d15 --- /dev/null +++ b/tests/ccgbugs/t13902.nim @@ -0,0 +1,12 @@ + +#issue #13902 +block: + type Slot = distinct uint64 + var s = Slot(1) + proc `$`(x: Slot): string {.borrow.} + proc `+=`(x: var Slot, y: uint64) {.borrow.} + # test was failing with either 0 or 2 echos but not with 1 echo + # echo "s = ", s + s += 1 + # echo "s = ", s + doAssert s.uint64 == 2, $s # was failing, showing 18419607611339964418 diff --git a/tests/ccgbugs/t15428.nim b/tests/ccgbugs/t15428.nim new file mode 100644 index 000000000..d9ae8ff16 --- /dev/null +++ b/tests/ccgbugs/t15428.nim @@ -0,0 +1,22 @@ +discard """ + cmd: "nim $target --mm:refc $file" + output: '''5 +5 +[1, 2, 3, 4, 5] +(data: [1, 2, 3, 4, 5]) +''' +""" + +proc take[T](f: openArray[T]) = + echo f.len +let f = @[0,1,2,3,4] +take(f.toOpenArray(0,4)) + +{.experimental: "views".} +type + Foo = object + data: openArray[int] +let f2 = Foo(data: [1,2,3,4,5]) +echo f2.data.len +echo f2.data +echo f2 \ No newline at end of file diff --git a/tests/ccgbugs/t16027.nim b/tests/ccgbugs/t16027.nim new file mode 100644 index 000000000..58f15eb6e --- /dev/null +++ b/tests/ccgbugs/t16027.nim @@ -0,0 +1,13 @@ +discard """ + ccodecheck: "__restrict__" + action: compile + joinable: false +""" + +# see bug #16027 +iterator myitems(s: seq[int]): int = + var data {.codegenDecl: "$# __restrict__ $#".} : ptr int = nil + yield 1 + +for i in @[1].myitems: + discard diff --git a/tests/ccgbugs/t16374.nim b/tests/ccgbugs/t16374.nim new file mode 100644 index 000000000..8ccfa4815 --- /dev/null +++ b/tests/ccgbugs/t16374.nim @@ -0,0 +1,38 @@ +discard """ + matrix: "--gc:refc; --gc:orc" +""" + +block: + iterator mvalues(t: var seq[seq[int]]): var seq[int] = + yield t[0] + + var t: seq[seq[int]] + + while false: + for v in t.mvalues: + discard + + proc ok = + while false: + for v in t.mvalues: + discard + + ok() + +block: + iterator mvalues(t: var seq[seq[int]]): lent seq[int] = + yield t[0] + + var t: seq[seq[int]] + + while false: + for v in t.mvalues: + discard + + proc ok = + while false: + for v in t.mvalues: + discard + + ok() + diff --git a/tests/ccgbugs/t19445.nim b/tests/ccgbugs/t19445.nim new file mode 100644 index 000000000..b6e8d028c --- /dev/null +++ b/tests/ccgbugs/t19445.nim @@ -0,0 +1,13 @@ +discard """ + matrix: "--nimcache:tests/ccgbugs/nimcache19445 --cincludes:nimcache19445 --header:m19445" + targets: "c" +""" + +# bug #19445 +type + Foo* {.exportc.} = object + a*, b*, c*, d*: int + +proc dummy(): Foo {.exportc.} = discard + +{.compile:"m19445.c".} \ No newline at end of file diff --git a/tests/ccgbugs/t20139.nim b/tests/ccgbugs/t20139.nim new file mode 100644 index 000000000..4592b994d --- /dev/null +++ b/tests/ccgbugs/t20139.nim @@ -0,0 +1,10 @@ +discard """ + joinable: false +""" + +# bug #20139 +import m1/defs as md1 +import m2/defs as md2 + +doAssert $(md1.MyObj(field1: 1)) == """(field1: 1, s: "", ch: '\x00')""" +doAssert $(md2.MyObj(field1: 1)) == """(s: "", field1: 1, ch: '\x00')""" diff --git a/tests/ccgbugs/t20141.nim b/tests/ccgbugs/t20141.nim new file mode 100644 index 000000000..60e130690 --- /dev/null +++ b/tests/ccgbugs/t20141.nim @@ -0,0 +1,27 @@ +discard """ + joinable: false +""" + +# bug #20141 +type + A = object + B = object + U = proc() + +proc m(h: var B) = discard + +template n[T, U](x: U): T = + static: doAssert true + cast[ptr T](addr x)[] + +proc k() = + var res: A + m(n[B, A](res)) + +proc w(mounter: U) = discard + +proc mount(proto: U) = discard +proc v() = mount k + +# This is required for failure +w(v) diff --git a/tests/ccgbugs/t20787.nim b/tests/ccgbugs/t20787.nim new file mode 100644 index 000000000..c2d848c2c --- /dev/null +++ b/tests/ccgbugs/t20787.nim @@ -0,0 +1,4 @@ +type + Obj = object + f: UncheckedArray[byte] +let o = new Obj \ No newline at end of file diff --git a/tests/ccgbugs/t21116.nim b/tests/ccgbugs/t21116.nim new file mode 100644 index 000000000..cc77de198 --- /dev/null +++ b/tests/ccgbugs/t21116.nim @@ -0,0 +1,10 @@ +discard """ + targets: "c cpp" + disabled: windows +""" +# bug #21116 +import std/os + +proc p(glob: string) = + for _ in walkFiles(glob): discard +p("dir/*") diff --git a/tests/ccgbugs/t21972.nim b/tests/ccgbugs/t21972.nim new file mode 100644 index 000000000..58d0cfc62 --- /dev/null +++ b/tests/ccgbugs/t21972.nim @@ -0,0 +1,33 @@ +discard """ + targets: "c cpp" + outputsub: "Error: unhandled exception: Err2 [IOError]" + exitcode: "1" +""" + +proc bar(x: var int) = + inc x + if x == 3: + raise newException(ValueError, "H0") + + elif x == 5: + raise newException(IOError, "H1") + + elif x > 7: + raise newException(IOError, "H2") + + +proc foo() = + var i = 0 + while true: + try: + bar(i) + echo i + + except ValueError: + debugEcho("ValueError") + + except IOError: + raise newException(IOError, "Err2") + +when isMainModule: + foo() \ No newline at end of file diff --git a/tests/ccgbugs/t21995.nim b/tests/ccgbugs/t21995.nim new file mode 100644 index 000000000..0ec88aa59 --- /dev/null +++ b/tests/ccgbugs/t21995.nim @@ -0,0 +1,9 @@ +discard """ + targets: "c cpp" + output: "Hi!" +""" + +try: + raise +except: + echo "Hi!" \ No newline at end of file diff --git a/tests/ccgbugs/t22462.nim b/tests/ccgbugs/t22462.nim new file mode 100644 index 000000000..9adfbb19b --- /dev/null +++ b/tests/ccgbugs/t22462.nim @@ -0,0 +1,20 @@ +discard """ + action: "run" + output: ''' +1 +1 +1 +''' + matrix: "--mm:refc" + targets: "c cpp" +""" + +type Object = object + someComplexType: seq[int] + index: Natural + +func newObject(): Object = result.index.inc + +for i in 1..3: + let o = newObject() + echo o.index diff --git a/tests/ccgbugs/t23796.nim b/tests/ccgbugs/t23796.nim new file mode 100644 index 000000000..421ec04d8 --- /dev/null +++ b/tests/ccgbugs/t23796.nim @@ -0,0 +1,25 @@ +discard """ + targets: "c cpp" +""" + +# bug #23796 + +{.emit: """ +#ifdef __cplusplus +extern "C" { +#endif + +void fooArr(float data[3]) {} +void fooIntArr(int id, float data[3]) {} + +#ifdef __cplusplus +} +#endif +""".} + +proc fooArr(data: var array[3, cfloat]) {.importc.} +proc fooIntArr(id: cint, data: var array[3, cfloat]) {.importc, nodecl.} + +var arr = [cfloat 1, 2, 3] +fooArr(arr) +fooIntArr(1, arr) diff --git a/tests/ccgbugs/t2procs.nim b/tests/ccgbugs/t2procs.nim new file mode 100644 index 000000000..d8b7a2815 --- /dev/null +++ b/tests/ccgbugs/t2procs.nim @@ -0,0 +1,18 @@ +discard """ + output: '''before +1 +before +2''' +""" + +proc fn[T1, T2](a: T1, b: T2) = + a(1) + b(2) + +fn( (proc(x: int) = + echo "before" # example block, can span multiple lines + echo x), + (proc (y: int) = + echo "before" + echo y) +) diff --git a/tests/ccgbugs/t5296.nim b/tests/ccgbugs/t5296.nim new file mode 100644 index 000000000..8fbed35c4 --- /dev/null +++ b/tests/ccgbugs/t5296.nim @@ -0,0 +1,21 @@ +discard """ +cmd: "nim c -d:release $file" +output: '''1 +-1''' +""" + +proc bug() : void = + var x = 0 + try: + inc x + raise new(Exception) + except Exception: + echo x + +bug() + +# bug #19051 +type GInt[T] = int + +var a = 1 +echo -a diff --git a/tests/ccgbugs/t5345.nim b/tests/ccgbugs/t5345.nim new file mode 100644 index 000000000..f9ee833c4 --- /dev/null +++ b/tests/ccgbugs/t5345.nim @@ -0,0 +1,10 @@ +discard """ + output: true +""" + +proc cmpx(d: int): bool {.inline.} = d > 0 + +proc abc[C](cx: C, d: int) = + echo cx(d) + +abc(cmpx, 10) diff --git a/tests/ccgbugs/t6279.nim b/tests/ccgbugs/t6279.nim new file mode 100644 index 000000000..5a3d6768c --- /dev/null +++ b/tests/ccgbugs/t6279.nim @@ -0,0 +1,9 @@ +discard """ +cmd: "nim c -r -d:fulldebug -d:smokeCycles --gc:refc $file" +output: '''@["a"]''' +""" + +# bug #6279 +var foo = newSeq[tuple[a: seq[string], b: seq[string]]]() +foo.add((@["a"], @["b"])) +echo foo[0].a # Crashes on this line diff --git a/tests/ccgbugs/t6756.nim b/tests/ccgbugs/t6756.nim new file mode 100644 index 000000000..5990eba58 --- /dev/null +++ b/tests/ccgbugs/t6756.nim @@ -0,0 +1,24 @@ +discard """ +output: ''' +(v: 3) +''' +""" + +import typetraits +type + A[T] = ref object + v: T + +template templ(o: A, op: untyped): untyped = + type T = typeof(o.v) + + var res: A[T] + + block: + var it {.inject.}: T + it = o.v + res = A[T](v: op) + res + +let a = A[int](v: 1) +echo templ(a, it + 2)[] diff --git a/tests/ccgbugs/t7079.nim b/tests/ccgbugs/t7079.nim new file mode 100644 index 000000000..bfa1b77a6 --- /dev/null +++ b/tests/ccgbugs/t7079.nim @@ -0,0 +1,9 @@ +discard """ + action: run + targets: '''c js''' +""" + +import math +let x = -0.0 +doAssert classify(x) == fcNegZero +doAssert classify(1 / -0.0) == fcNegInf \ No newline at end of file diff --git a/tests/ccgbugs/t8616.nim b/tests/ccgbugs/t8616.nim new file mode 100644 index 000000000..5fd940d3b --- /dev/null +++ b/tests/ccgbugs/t8616.nim @@ -0,0 +1,4 @@ +import pkg8616 / scheduler + +when true: + init() diff --git a/tests/ccgbugs/t8781.nim b/tests/ccgbugs/t8781.nim new file mode 100644 index 000000000..884c6962a --- /dev/null +++ b/tests/ccgbugs/t8781.nim @@ -0,0 +1,25 @@ +discard """ +output: "" +""" + +type + Drawable = object of RootObj + discard + + # issue #8781, following type was broken due to 'U' suffix + # on `animatedU`. U also added as union identifier for C. + # replaced by "_U" prefix, which is not allowed as an + # identifier + TypeOne = ref object of Drawable + animatedU: bool + case animated: bool + of true: + frames: seq[int] + of false: + region: float + +when true: + let r = 1.5 + let a = TypeOne(animatedU: true, + animated: false, + region: r) diff --git a/tests/ccgbugs/t8967.nim b/tests/ccgbugs/t8967.nim new file mode 100644 index 000000000..0301a2e4f --- /dev/null +++ b/tests/ccgbugs/t8967.nim @@ -0,0 +1,14 @@ +discard """ + targets: "c cpp" +""" + +import marshal + +template main() = + let orig: set[char] = {'A'..'Z'} + let m = $$orig + let old = to[set[char]](m) + doAssert orig - old == {} + +static: main() +main() diff --git a/tests/ccgbugs/t9098.nim b/tests/ccgbugs/t9098.nim new file mode 100644 index 000000000..e1dbb6883 --- /dev/null +++ b/tests/ccgbugs/t9098.nim @@ -0,0 +1,12 @@ +discard """ + targets: "c cpp js" + output: ''' +{'a', 'b'} +''' +""" + +var x = new(ref set[char]) +var y = new(ref set[char]) +x[] = {'a'} +y[] = {'b'} +echo x[] + y[] diff --git a/tests/ccgbugs/t9286.nim b/tests/ccgbugs/t9286.nim new file mode 100644 index 000000000..2fec23307 --- /dev/null +++ b/tests/ccgbugs/t9286.nim @@ -0,0 +1,22 @@ +discard """ + action: run +""" + +import options +type Foo = ref object + i: int + +proc next(foo: Foo): Option[Foo] = + try: doAssert(foo.i == 0) + except: return # 2º: none + return some(foo) # 1º: some + +proc test = + let foo = Foo() + var opt = next(foo) # 1º Some + while isSome(opt) and foo.i < 10: + inc(foo.i) + opt = next(foo) # 2º None + doAssert foo.i == 1, $foo.i + +test() diff --git a/tests/ccgbugs/t9578.nim b/tests/ccgbugs/t9578.nim new file mode 100644 index 000000000..25b7b6695 --- /dev/null +++ b/tests/ccgbugs/t9578.nim @@ -0,0 +1,76 @@ +discard """ +output: ''' +@[(v: -1), (v: 2), (v: 3)] +@[(v: -1), (v: 2), (v: 3)] +[(v: -1), (v: 2), (v: 3)] +[(v: -1), (v: 2), (v: 3)] +((v: -1), (v: 2), (v: 3)) +((v: -1), (v: 2), (v: 3)) +@[(v: -1), (v: 2), (v: 3)] +@[(v: -1), (v: 2), (v: 3)] +@[(v: -1), (v: 2), (v: 3)] +''' +""" + +type mytype* = object + v:int + +proc f*(x:ptr mytype) = x.v = -1 + +func g(x:int):mytype = mytype(v:x) + + +import xseq9578 +block: + var x = @[1.g,2.g,3.g] + testSeq(x) + echo x +block: + var x = @[1.g,2.g,3.g] + var y = addr x + testSeq2(y) + echo x + + +import xarray9578 +block: + var x = [1.g,2.g,3.g] + testArray(x) + echo x +block: + var x = [1.g,2.g,3.g] + var y = addr x + testArray2(y) + echo x + + +import xtuple9578 +block: + var x = (1.g,2.g,3.g) + testTuple(x) + echo x +block: + var x = (1.g,2.g,3.g) + var y = addr x + testTuple2(y) + echo x + + +import xoa9578 +block: + var x = @[1.g,2.g,3.g] + testOpenArray(x) + echo x + + +import xua9578 +block: + var x = @[1.g,2.g,3.g] + var y = cast[ptr UncheckedArray[mytype]](addr x[0]) + testUncheckedArray(y[]) + echo x +block: + var x = @[1.g,2.g,3.g] + var y = cast[ptr UncheckedArray[mytype]](addr x[0]) + testUncheckedArray2(y) + echo x diff --git a/tests/ccgbugs/t9655.nim b/tests/ccgbugs/t9655.nim new file mode 100644 index 000000000..29fb903a4 --- /dev/null +++ b/tests/ccgbugs/t9655.nim @@ -0,0 +1,30 @@ +discard """ + action: "compile" +""" + +import std/[asynchttpserver, asyncdispatch] +import std/[strformat] + +proc main() = + let local = "123" + + proc serveIndex(req: Request) {.async, gcsafe.} = + await req.respond(Http200, &"{local}") + + proc serve404(req: Request) {.async, gcsafe.} = + echo req.url.path + await req.respond(Http404, "not found") + + proc serve(req: Request) {.async, gcsafe.} = + let handler = case req.url.path: + of "/": + serveIndex + else: + serve404 + await handler(req) + + let server = newAsyncHttpServer() + waitFor server.serve(Port(8080), serve, address = "127.0.0.1") + +when isMainModule: + main() diff --git a/tests/ccgbugs/taddhigh.nim b/tests/ccgbugs/taddhigh.nim new file mode 100644 index 000000000..6b0658612 --- /dev/null +++ b/tests/ccgbugs/taddhigh.nim @@ -0,0 +1,19 @@ +discard """ + output: '''@[5, 5, 5, 5, 5]''' +""" + +# bug #1832 + +var s = @[5] + +# Works fine: +let x = s[s.high] +s.add x + +# Causes the 0 to appear: +s.add s[s.high] + +s.add s[s.len-1] +s.add s[s.len-1] + +echo s # @[5, 5, 0] diff --git a/tests/ccgbugs/targ_lefttoright.nim b/tests/ccgbugs/targ_lefttoright.nim new file mode 100644 index 000000000..a0adce157 --- /dev/null +++ b/tests/ccgbugs/targ_lefttoright.nim @@ -0,0 +1,71 @@ +discard """ + nimout: '''1,2 +2,3 +2,2 +1,2 +1,2 +2,2 +1,2 +''' + output: '''1,2 +2,3 +1,2 +2,2 +1,2 +1,2 +2,2 +1,2 +''' + cmd: "nim c --gc:orc $file" +""" + +template test = + proc say(a, b: int) = + echo a,",",b + + var a = 1 + say a, (a += 1; a) #1,2 + + var b = 1 + say (b += 1; b), (b += 1; b) #2,3 + + type C {.byRef.} = object + i: int + + proc say(a, b: C) = + echo a.i,",",b.i + + proc `+=`(x: var C, y: C) = x.i += y.i + + var c = C(i: 1) + when nimvm: #XXX: This would output 2,2 in the VM, which is wrong + discard + else: + say c, (c += C(i: 1); c) #1,2 + + proc sayVar(a: var int, b: int) = + echo a,",",b + + var d = 1 + sayVar d, (d += 1; d) #2,2 + + var e = 1 + say (addr e)[], (e += 1; e) #1,2 + + var f = 1 + say f, if false: f + else: f += 1; f #1,2 + + var g = 1 + say g + 1, if false: g + else: g += 1; g #2,2 + + proc `+=+`(x: var int, y: int): int = (inc(x, y); x) + + var h = 1 + say h, h +=+ 1 # 1,2 + +test + +static: + test diff --git a/tests/ccgbugs/tarray_equality.nim b/tests/ccgbugs/tarray_equality.nim new file mode 100644 index 000000000..66a953439 --- /dev/null +++ b/tests/ccgbugs/tarray_equality.nim @@ -0,0 +1,15 @@ +discard """ + output: '''true +true''' +""" + +# bug #2489 + +let a = [1] +let b = [1] +echo a == b + +# bug #2498 +var x: array[0, int] +var y: array[0, int] +echo x == y diff --git a/tests/ccgbugs/tassign_nil_strings.nim b/tests/ccgbugs/tassign_nil_strings.nim new file mode 100644 index 000000000..e32bfcade --- /dev/null +++ b/tests/ccgbugs/tassign_nil_strings.nim @@ -0,0 +1,13 @@ +discard """ + matrix: "--mm:refc" + output: "Hello" + ccodecheck: "\\i@'a = ((NimStringDesc*) NIM_NIL)'" +""" + +proc main() = + var a = "Hello" + echo a + a = "" + doAssert a.len == 0 + +main() diff --git a/tests/ccgbugs/tborrowmagic.nim b/tests/ccgbugs/tborrowmagic.nim new file mode 100644 index 000000000..8d42ddcd8 --- /dev/null +++ b/tests/ccgbugs/tborrowmagic.nim @@ -0,0 +1,8 @@ +type + Bytes = distinct seq[byte] + +proc add(x: var Bytes; b: byte) {.borrow.} +var x = @[].Bytes +x.add(42) +let base = cast[seq[byte]](x) +doAssert base.len == 1 and base[0] == 42 diff --git a/tests/ccgbugs/tbug1081.nim b/tests/ccgbugs/tbug1081.nim new file mode 100644 index 000000000..baef99d84 --- /dev/null +++ b/tests/ccgbugs/tbug1081.nim @@ -0,0 +1,34 @@ +discard """ + output: '''1 +0 +0 +0 +x = ['a', 'b', 'c', '0', '1', '2', '3', '4', '5', '6'] and y = ['a', 'b', 'c', '0', '1', '2', '3', '4', '5', '6']''' +""" + +proc `1/1`() = echo(1 div 1) +template `1/2`() = echo(1 div 2) +var `1/3` = 1 div 4 +`1/3` = 1 div 3 # oops, 1/3!=1/4 +let `1/4` = 1 div 4 + +`1/1`() +`1/2`() +echo `1/3` +echo `1/4` + +# bug #6422 + +proc toCharArray1(N : static[int], s: string): array[N, char] = + doAssert s.len <= N + let x = cast[ptr array[N, char]](s.cstring) + x[] + +proc toCharArray2(N : static[int], s: string): array[N, char] = + doAssert s.len <= N + let x = cast[ptr array[N, char]](s.cstring) + result = x[] + +let x = toCharArray1(10, "abc0123456") +let y = toCharArray2(10, "abc0123456") +echo "x = ", $x, " and y = ", $y diff --git a/tests/ccgbugs/tbug21505.nim b/tests/ccgbugs/tbug21505.nim new file mode 100644 index 000000000..0c0811ec5 --- /dev/null +++ b/tests/ccgbugs/tbug21505.nim @@ -0,0 +1,39 @@ +discard """ + action: "compile" + targets: "cpp" + cmd: "nim cpp $file" +""" + +# see #21505: ensure compilation of imported C++ objects with explicit constructors while retaining default initialization through codegen changes due to #21279 + +{.emit:"""/*TYPESECTION*/ + +struct ExplObj +{ + explicit ExplObj(int bar = 0) {} +}; + +struct BareObj +{ + BareObj() {} +}; + +""".} + +type + ExplObj {.importcpp.} = object + BareObj {.importcpp.} = object + +type + Composer = object + explObj: ExplObj + bareObj: BareObj + +proc foo = + var composer1 {.used.}: Composer + let composer2 {.used.} = Composer() + +var composer1 {.used.}: Composer +let composer2 {.used.} = Composer() + +foo() \ No newline at end of file diff --git a/tests/ccgbugs/tcapture_static.nim b/tests/ccgbugs/tcapture_static.nim new file mode 100644 index 000000000..2afb8de47 --- /dev/null +++ b/tests/ccgbugs/tcapture_static.nim @@ -0,0 +1,13 @@ +discard """ + output: '''hi''' +""" + +# bug #4551 + +proc foo() = + let arr = ["hi"] + for i, v in arr: + let bar = proc = + echo v + bar() +foo() diff --git a/tests/ccgbugs/tccgen1.nim b/tests/ccgbugs/tccgen1.nim new file mode 100644 index 000000000..be571de08 --- /dev/null +++ b/tests/ccgbugs/tccgen1.nim @@ -0,0 +1,67 @@ + + +type + Feature = tuple[name: string, version: string] + PDOMImplementation* = ref DOMImplementation + DOMImplementation = object + Features: seq[Feature] # Read-Only + + PNode* = ref Node + Node {.inheritable.} = object + attributes*: seq[PAttr] + childNodes*: seq[PNode] + FLocalName: string # Read-only + FNamespaceURI: string # Read-only + FNodeName: string # Read-only + nodeValue*: string + FNodeType: int # Read-only + FOwnerDocument: PDocument # Read-Only + FParentNode: PNode # Read-Only + prefix*: string # Setting this should change some values... TODO! + + PElement* = ref Element + Element = object of Node + FTagName: string # Read-only + + PCharacterData = ref CharacterData + CharacterData = object of Node + data*: string + + PDocument* = ref Document + Document = object of Node + FImplementation: PDOMImplementation # Read-only + FDocumentElement: PElement # Read-only + + PAttr* = ref Attr + Attr = object of Node + FName: string # Read-only + FSpecified: bool # Read-only + value*: string + FOwnerElement: PElement # Read-only + + PDocumentFragment* = ref DocumentFragment + DocumentFragment = object of Node + + PText* = ref Text + Text = object of CharacterData + + PComment* = ref Comment + Comment = object of CharacterData + + PCDataSection* = ref CDataSection + CDataSection = object of Text + + PProcessingInstruction* = ref ProcessingInstruction + ProcessingInstruction = object of Node + data*: string + FTarget: string # Read-only + +proc `namespaceURI=`*(n: var PNode, value: string) = + n.FNamespaceURI = value + +proc main = + var n: PNode + new(n) + n.namespaceURI = "test" + +main() diff --git a/tests/ccgbugs/tccgissues.nim b/tests/ccgbugs/tccgissues.nim new file mode 100644 index 000000000..8207ccbba --- /dev/null +++ b/tests/ccgbugs/tccgissues.nim @@ -0,0 +1,14 @@ +discard """ + output: ''' +@[1, 2, 3, 4] +''' +""" + +# issue #10999 + +proc varargsToSeq(vals: varargs[int32]): seq[int32] = + result = newSeqOfCap[int32](vals.len) + for v in vals: + result.add v + +echo varargsToSeq(1, 2, 3, 4) diff --git a/tests/ccgbugs/tcgbug.nim b/tests/ccgbugs/tcgbug.nim new file mode 100644 index 000000000..2eddc6fdd --- /dev/null +++ b/tests/ccgbugs/tcgbug.nim @@ -0,0 +1,163 @@ +discard """ +output: ''' +success +M1 M2 +ok +''' +matrix: "--mm:refc;--mm:orc" +""" + +type + TObj = object + x, y: int + PObj = ref TObj + +proc p(a: PObj) = + a.x = 0 + +proc q(a: var PObj) = + a.p() + +var + a: PObj +new(a) +q(a) + +# bug #914 +when defined(windows): + import std/widestrs + var x = newWideCString("Hello") + +echo "success" + + +# bug #833 + +type + PFuture*[T] = ref object + value*: T + finished*: bool + cb: proc (future: PFuture[T]) {.closure.} + +var k = PFuture[void]() + + +##bug #9297 and #13281 + +import strutils + +type + MyKind = enum + M1, M2, M3 + + MyObject {.exportc: "ExtObject"} = object + case kind: MyKind + of M1: a:int + of M2: b:float + of M3: c:cstring + + MyObjectRef {.exportc: "ExtObject2"} = ref object + case kind: MyKind + of M1: a:int + of M2: b:float + of M3: c:cstring + + Helper* {.exportc: "PublicHelper".} = object + case isKind: bool + of true: + formatted: string + of false: + parsed1: string + parsed2: string + +proc newMyObject(kind: MyKind, val: string): MyObject = + result = MyObject(kind: kind) + + case kind + of M1: result.a = parseInt(val) + of M2: result.b = parseFloat(val) + of M3: result.c = val + +proc newMyObjectRef(kind: MyKind, val: string): MyObjectRef = + result = MyObjectRef(kind: kind) + case kind + of M1: result.a = parseInt(val) + of M2: result.b = parseFloat(val) + of M3: result.c = val + + +echo newMyObject(M1, "2").kind, " ", newMyObjectRef(M2, "3").kind + + +proc test(c: Helper): string = + c.formatted + +echo test(Helper(isKind: true, formatted: "ok")) + + +# bug #19613 + +type + Eth2Digest = object + data: array[42, byte] + + BlockId* = object + root*: Eth2Digest + + BlockSlotId* = object + bid*: BlockId + slot*: uint64 + +func init*(T: type BlockSlotId, bid: BlockId, slot: uint64): T = + #debugecho "init ", bid, " ", slot + BlockSlotId(bid: bid, slot: slot) + +proc bug19613 = + var x: BlockSlotId + x.bid.root.data[0] = 42 + + x = + if x.slot > 0: + BlockSlotId.init(x.bid, x.slot) + else: + BlockSlotId.init(x.bid, x.slot) + doAssert x.bid.root.data[0] == 42 + +bug19613() + +proc foo = # bug #23280 + let foo = @[1,2,3,4,5,6] + doAssert toOpenArray(foo, 0, 5).len == 6 + doAssert toOpenArray(foo, 0, 5).len mod 6 == 0 # this should output 0 + doAssert toOpenArray(foo, 0, 5).max mod 6 == 0 + let L = toOpenArray(foo, 0, 5).len + doAssert L mod 6 == 0 + +foo() + +block: # bug #9940 + {.emit:"""/*TYPESECTION*/ +typedef struct { int base; } S; +""".} + + type S {.importc: "S", completeStruct.} = object + base: cint + proc init(x:ptr S) = + x.base = 1 + + type + Foo = object + a: seq[float] + b: seq[float] + c: seq[float] + d: seq[float] + s: S + + proc newT(): Foo = + var t: Foo + t.s.addr.init + doAssert t.s.base == 1 + t + + var t = newT() + doAssert t.s.base == 1 diff --git a/tests/ccgbugs/tclosureeq.nim b/tests/ccgbugs/tclosureeq.nim new file mode 100644 index 000000000..0486a9559 --- /dev/null +++ b/tests/ccgbugs/tclosureeq.nim @@ -0,0 +1,19 @@ +discard """ + output: '''true +true''' +""" + +# bug #4186 +type + Predicate[T] = proc(item: T): bool + +proc a[T](): Predicate[T] = + return nil + +proc b[T](): Predicate[T] = + return a[T]() + +echo b[int]() == nil # ok + +let x = b[int]() +echo x == nil #won't compile diff --git a/tests/ccgbugs/tcodegenbug1.nim b/tests/ccgbugs/tcodegenbug1.nim new file mode 100644 index 000000000..d2ab97ede --- /dev/null +++ b/tests/ccgbugs/tcodegenbug1.nim @@ -0,0 +1,185 @@ +discard """ + matrix: "--mm:refc" + output: '''obj = (inner: (kind: Just, id: 7)) +obj.inner.id = 7 +id = 7 +obj = (inner: (kind: Just, id: 7)) +2 +(a: "a", b: "b", c: "") +caught +(a: "a", b: "b", c: "")''' +""" + +# bug #6960 + +import sugar +type + Kind = enum None, Just, Huge + Inner = object + case kind: Kind + of None: discard + of Just: id: int + of Huge: a,b,c,d,e,f: string + Outer = object + inner: Inner + + +proc shouldDoNothing(id: int): Inner = + dump id + Inner(kind: Just, id: id) + +var obj = Outer(inner: Inner(kind: Just, id: 7)) +dump obj +dump obj.inner.id +obj.inner = shouldDoNothing(obj.inner.id) +dump obj + +import os + +type + TStatusEnum* = enum + sUnknown = -1, sBuildFailure, sBuildInProgress, sBuildSuccess, + sTestFailure, sTestInProgress, sTestSuccess, # ORDER MATTERS! + sDocGenFailure, sDocGenInProgress, sDocGenSuccess, + sCSrcGenFailure, sCSrcGenInProgress, sCSrcGenSuccess + + TStatus* = object + status*: TStatusEnum + desc*: string + hash*: string + +proc initStatus*(): TStatus = + result.status = sUnknown + result.desc = "" + result.hash = "" + +proc isInProgress*(status: TStatusEnum): bool = + return status in {sBuildInProgress, sTestInProgress, sDocGenInProgress, + sCSrcGenInProgress} + +proc `$`*(status: TStatusEnum): string = + case status + of sBuildFailure: + return "build failure" + of sBuildInProgress: + return "build in progress" + of sBuildSuccess: + return "build finished" + of sTestFailure: + return "testing failure" + of sTestInProgress: + return "testing in progress" + of sTestSuccess: + return "testing finished" + of sDocGenFailure: + return "documentation generation failed" + of sDocGenInProgress: + return "generating documentation" + of sDocGenSuccess: + return "documentation generation succeeded" + of sCSrcGenFailure: + return "csource generation failed" + of sCSrcGenInProgress: + return "csource generation in progress" + of sCSrcGenSuccess: + return "csource generation succeeded" + of sUnknown: + return "unknown" + +proc makeCommitPath*(platform, hash: string): string = + return platform / "nim_" & hash.substr(0, 11) # 11 Chars. + +type + TFlag = enum + A, B, C, D + + TFlags = set[TFlag] + + TObj = object + x: int + flags: TFlags + +# have a proc taking TFlags as param and returning object having TFlags field +proc foo(flags: TFlags): TObj = nil + + +# bug #5137 +type + MyInt {.importc: "int".} = object + MyIntDistinct = distinct MyInt + +proc bug5137(d: MyIntDistinct) = + discard d.MyInt + +#------------------------------------- +# bug #8979 + +type + MyKind = enum + Fixed, Float + + MyObject = object + someInt: int + case kind: MyKind + of Float: index: string + of Fixed: nil + + MyResult = object + val: array[0..1, string] + vis: set[0..1] + +import macros + +func myfunc(obj: MyObject): MyResult {.raises: [].} = + template index: auto = + case obj.kind: + of Float: $obj.index + of Fixed: "Fixed" + macro to_str(a: untyped): string = + result = newStrLitNode(a.repr) + result.val[0] = index + result.val[1] = to_str(obj.kind + Ola) + +let x = MyObject(someInt: 10, kind: Fixed) +echo myfunc(x).val.len + +# bug #14126 + +type X = object + a, b, c: string + +proc f(): X = + result.a = "a" + result.b = "b" + raise (ref ValueError)() + +proc ohmanNoNRVO = + var x: X + x.a = "1" + x.b = "2" + x.c = "3" + + try: + x = f() + except: + discard + + echo x + # once NVRO is sorted out, x.c == "3" + doAssert x.c == "", "shouldn't modify x if f raises" + +ohmanNoNRVO() + +proc ohmanNoNRVO2(x: var X) = + x.a = "1" + x.c = "3" + x = f() + +var xgg: X +try: + ohmanNoNRVO2(xgg) +except: + echo "caught" +echo xgg +# once NVRO is sorted out, xgg.c == "3" +doAssert xgg.c == "", "this assert will fail" diff --git a/tests/ccgbugs/tcodegenbug_bool.nim b/tests/ccgbugs/tcodegenbug_bool.nim new file mode 100644 index 000000000..a0dbf4eb2 --- /dev/null +++ b/tests/ccgbugs/tcodegenbug_bool.nim @@ -0,0 +1,11 @@ +discard """ +""" + +# issue #13798 +{.emit:""" +#include <stdbool.h> +void fun(bool a){} +""".} + +proc fun(a: bool) {.importc.} +fun(true) diff --git a/tests/ccgbugs/tcodegendecllambda.nim b/tests/ccgbugs/tcodegendecllambda.nim new file mode 100644 index 000000000..814dcf206 --- /dev/null +++ b/tests/ccgbugs/tcodegendecllambda.nim @@ -0,0 +1,14 @@ +discard """ + targets: "c cpp js" + ccodecheck: "'HELLO'" + action: compile +""" + +when defined(js): + var foo = proc(): void{.codegenDecl: "/*HELLO*/function $2($3)".} = + echo "baa" +else: + var foo = proc(): void{.codegenDecl: "/*HELLO*/$1 $2 $3".} = + echo "baa" + +foo() diff --git a/tests/ccgbugs/tcompile_time_var_at_runtime.nim b/tests/ccgbugs/tcompile_time_var_at_runtime.nim new file mode 100644 index 000000000..c0de0390b --- /dev/null +++ b/tests/ccgbugs/tcompile_time_var_at_runtime.nim @@ -0,0 +1,11 @@ +discard """ + output: "1\n2\n2\n3" +""" +var a {.compileTime.} = 1 + +echo a +a = 2 +echo a +echo a +a = 3 +echo a \ No newline at end of file diff --git a/tests/ccgbugs/tctypes.nim b/tests/ccgbugs/tctypes.nim new file mode 100644 index 000000000..be6009115 --- /dev/null +++ b/tests/ccgbugs/tctypes.nim @@ -0,0 +1,43 @@ +discard """ + targets: "c cpp" + matrix: "--gc:refc; --gc:arc" +""" + +# bug #7308 +proc foo(x: seq[int32]) = + var y = newSeq[cint](1) + +proc bar = + var t = newSeq[int32](1) + foo(t) + +bar() + + +# bug #16246 + +proc testWeirdTypeAliases() = + var values = newSeq[cuint](8) + # var values: seq[cuint] does not produce codegen error + var drawCb = proc(): seq[uint32] = + result = newSeq[uint32](10) + +testWeirdTypeAliases() + +block: # bug #11797 + block: + type cdouble2 = cdouble + type Foo1 = seq[cdouble] + type Foo2 = seq[cdouble2] + static: doAssert Foo1 is Foo2 + var a1: Foo1 + var a2: Foo2 + doAssert a1 == @[] + doAssert a2 == @[] + + block: + proc foo[T: int|cint](fun: proc(): T) = discard + proc foo1(): cint = 1 + proc foo3(): int32 = 2 + foo(proc(): cint = foo1()) + foo(proc(): int32 = foo3()) diff --git a/tests/ccgbugs/tcvarargs.nim b/tests/ccgbugs/tcvarargs.nim new file mode 100644 index 000000000..261885f4f --- /dev/null +++ b/tests/ccgbugs/tcvarargs.nim @@ -0,0 +1,35 @@ +discard """ + output: '''17 +17 +17 +17 +17 +17 +''' +""" + +# bug #1593 + +{.emit: """ +#include <stdarg.h> +#include <stdio.h> + +void foo(int n, ...) { + NI64 k; + int i; + va_list argp; + va_start(argp, n); + for (i = 1; i <= n; i++) { + k = va_arg(argp, NI64); + printf("%lld\n", (long long)k); + } + va_end(argp); +} +""".} + +proc foo(x: cint) {.importc, varargs, nodecl.} + +proc main() = + const k = 17'i64 + foo(6, k, k, k, k, k, k) +main() diff --git a/tests/ccgbugs/tdeepcopy_addr_rval.nim b/tests/ccgbugs/tdeepcopy_addr_rval.nim new file mode 100644 index 000000000..4a0b0deaa --- /dev/null +++ b/tests/ccgbugs/tdeepcopy_addr_rval.nim @@ -0,0 +1,17 @@ +discard """ + matrix: "--mm:refc; --mm:orc --deepcopy:on" + output: "3" +""" + +# issue 5166 + +type + Test = ref object + x: int + +let x = Test(x: 3) +let p = cast[pointer](x) + +var v: Test +deepCopy(v, cast[Test](p)) +echo v.x diff --git a/tests/ccgbugs/tderefblock.nim b/tests/ccgbugs/tderefblock.nim new file mode 100644 index 000000000..d3ba07667 --- /dev/null +++ b/tests/ccgbugs/tderefblock.nim @@ -0,0 +1,76 @@ +discard """ + matrix: "--mm:refc -d:release -d:danger;--mm:orc -d:useMalloc -d:release -d:danger" + output: "42" +""" + +# bug #20107 + +type Foo = object + a, b, c, d: uint64 + +proc c(i: uint64): Foo = + Foo(a: i, b: i, c: i, d: i) + +func x(f: Foo): lent Foo {.inline.} = + f + +proc m() = + let f = block: + let i = c(42) + x(i) + + echo $f.a + +m() + +block: # bug #21540 + type + Option = object + val: string + has: bool + + proc some(val: string): Option = + result.has = true + result.val = val + + # Remove lent and it works + proc get(self: Option): lent string = + result = self.val + + type + StringStream = ref object + data: string + pos: int + + proc readAll(s: StringStream): string = + result = newString(s.data.len) + copyMem(addr(result[0]), addr(s.data[0]), s.data.len) + + proc newStringStream(s: string = ""): StringStream = + new(result) + result.data = s + + proc parseJson(s: string): string = + let stream = newStringStream(s) + result = stream.readAll() + + proc main = + let initialFEN = block: + let initialFEN = some parseJson("startpos") + initialFEN.get + + doAssert initialFEN == "startpos" + + main() + +import std/[ + json, + options +] + +block: # bug #21540 + let cheek = block: + let initialFEN = some("""{"initialFen": "startpos"}""".parseJson{"initialFen"}.getStr) + initialFEN.get + + doAssert cheek == "startpos" diff --git a/tests/ccgbugs/tescaping_temps.nim b/tests/ccgbugs/tescaping_temps.nim new file mode 100644 index 000000000..ea09261ea --- /dev/null +++ b/tests/ccgbugs/tescaping_temps.nim @@ -0,0 +1,31 @@ + +# bug #4505 + +proc f(t: tuple[]) = discard +f((block: ())) + +# bug #4230 +# If we make `test` function return nothing - the bug disappears +proc test(dothejob: proc()): int {.discardable.} = + dothejob() + +test proc() = + let f = 15 + if f > 10: + test proc() = discard + # If we remove elif branch of the condition - the bug disappears + elif f < 3: + test proc() = discard + else: + test proc() = discard + +# ensure 'case' does not trigger the same bug: +test proc() = + let f = 15 + case f + of 10: + test proc() = discard + of 3: + test proc() = discard + else: + test proc() = discard diff --git a/tests/ccgbugs/tforward_decl_only.nim b/tests/ccgbugs/tforward_decl_only.nim new file mode 100644 index 000000000..b115dcbe7 --- /dev/null +++ b/tests/ccgbugs/tforward_decl_only.nim @@ -0,0 +1,34 @@ +discard """ +ccodecheck: "\\i !@('struct tyObject_MyRefObject'[0-z]+' _')" +output: "hello" +""" + +# issue #7339 +# Test that MyRefObject is only forward declared as it used only by reference + +import mymodule +type AnotherType = object + f: MyRefObject + +let x = AnotherType(f: newMyRefObject("hello")) +echo $x.f + + +# bug #7363 + +type + Foo = object + a: cint + Foo2 = object + b: cint + +proc f(foo: ptr Foo, foo2: ptr Foo2): cint = + if foo != nil: {.emit: "`result` = `foo`->a;".} + if foo2 != nil: {.emit: [result, " = ", foo2[], ".b;"].} + +discard f(nil, nil) + + +# bug #7392 +var x1: BaseObj +var x2 = ChildObj(x1) diff --git a/tests/ccgbugs/tgeneric_closure.nim b/tests/ccgbugs/tgeneric_closure.nim new file mode 100644 index 000000000..9f3c5b446 --- /dev/null +++ b/tests/ccgbugs/tgeneric_closure.nim @@ -0,0 +1,34 @@ +discard """ +output: ''' +2 +2 +2 +''' +""" + +# bug 2659 + +type + GenProcType[T,U] = proc(x:T, y:var U) + IntProcType = proc(x:int, y:var int) + +proc mult(x:int, y:var int) = + y = 2 * x + +when true: + + var input = 1 + var output = 0 + + var someIntProc:IntProcType = mult + var someGenProc:GenProcType[int,int] = mult + + mult(input, output) + echo output + + someIntProc(input, output) + echo output + + # Uncommenting causes an error in the C compiler. + someGenProc(input, output) + echo output diff --git a/tests/ccgbugs/tgeneric_smallobj_asgn_opt.nim b/tests/ccgbugs/tgeneric_smallobj_asgn_opt.nim new file mode 100644 index 000000000..3788b9985 --- /dev/null +++ b/tests/ccgbugs/tgeneric_smallobj_asgn_opt.nim @@ -0,0 +1,27 @@ +discard """ + output: "done generic smallobj asgn opt" +""" + +# bug #5402 + +import lists + +type + Container[T] = ref object + obj: T + + ListOfContainers[T] = ref object + list: DoublyLinkedList[Container[T]] + +proc contains[T](this: ListOfContainers[T], obj: T): bool = + for item in this.list.items(): + if item.obj == obj: return true + return false + +proc newListOfContainers[T](): ListOfContainers[T] = + new(result) + result.list = initDoublyLinkedList[Container[T]]() + +let q = newListOfContainers[int64]() +if not q.contains(123): + echo "done generic smallobj asgn opt" diff --git a/tests/ccgbugs/thtiobj.nim b/tests/ccgbugs/thtiobj.nim new file mode 100644 index 000000000..6db24dad0 --- /dev/null +++ b/tests/ccgbugs/thtiobj.nim @@ -0,0 +1,9 @@ +discard """ + matrix: "--mm:refc" + targets: "c cpp" +""" + +import typeinfo + +var x = "" +discard (getPointer(toAny(x))) diff --git a/tests/ccgbugs/tissues.nim b/tests/ccgbugs/tissues.nim new file mode 100644 index 000000000..a0c402cc0 --- /dev/null +++ b/tests/ccgbugs/tissues.nim @@ -0,0 +1,38 @@ +discard """ +action: compile +""" + +# bug #2233 +type MalType = object + fun: proc: MalType + +proc f(x: proc: MalType) = + discard x() + +f(nil) + +# bug #2823 + +type A = object #of RootObj <-- Uncomment this to get no errors + test: proc(i: A): bool +var a: proc(i: A): bool # Or comment this line to get no errors + + +# bug #2703 +type + fooObj[T] = object of RootObj + bazObj[T] = object of fooObj[T] + x: T + +var troz: fooObj[string] +echo bazObj[string](troz).x + + +# bug #14880 +type step = object + exec: proc () + +const pipeline = @[step()] + +let crash = pipeline[0] + diff --git a/tests/ccgbugs/tlvalueconv.nim b/tests/ccgbugs/tlvalueconv.nim new file mode 100644 index 000000000..b2cb11eef --- /dev/null +++ b/tests/ccgbugs/tlvalueconv.nim @@ -0,0 +1,32 @@ +discard """ + matrix: "--gc:refc; --gc:arc" +""" + +# bug #14160 + +type + TPassContext = object of RootObj + PPassContext = ref TPassContext + + PCtx = ref object of TPassContext + a: int + + ModuleGraph = object + vm: RootRef + +proc main() = + var g = ModuleGraph(vm: new(Pctx)) + PCtx(g.vm) = nil #This generates invalid C code + doAssert g.vm == nil + +main() + +# bug #14325 + +proc main2() = + var g = ModuleGraph(vm: new(Pctx)) + PPassContext(PCtx(g.vm)) = nil #This compiles, but crashes at runtime with gc:arc + doAssert g.vm == nil + +main2() + diff --git a/tests/ccgbugs/tmangle.nim b/tests/ccgbugs/tmangle.nim new file mode 100644 index 000000000..0050cef92 --- /dev/null +++ b/tests/ccgbugs/tmangle.nim @@ -0,0 +1,16 @@ +block: + proc hello() = + let NAN_INFINITY = 12 + doAssert NAN_INFINITY == 12 + let INF = "2.0" + doAssert INF == "2.0" + let NAN = 2.3 + doAssert NAN == 2.3 + + hello() + +block: + proc hello(NAN: float) = + doAssert NAN == 2.0 + + hello(2.0) diff --git a/tests/ccgbugs/tmangle_field.nim b/tests/ccgbugs/tmangle_field.nim new file mode 100644 index 000000000..da2720aaa --- /dev/null +++ b/tests/ccgbugs/tmangle_field.nim @@ -0,0 +1,16 @@ +discard """ +""" + +# bug #5404 + +import parseopt + +{.emit: """typedef struct { + int key; +} foo;""".} + +type foo* {.importc: "foo", nodecl.} = object + key* {.importc: "key".}: cint + +for kind, key, value in parseopt.getopt(): + discard diff --git a/tests/ccgbugs/tmarkerproc_regression.nim b/tests/ccgbugs/tmarkerproc_regression.nim new file mode 100644 index 000000000..3b606b834 --- /dev/null +++ b/tests/ccgbugs/tmarkerproc_regression.nim @@ -0,0 +1,47 @@ +discard """ + output: "done markerproc regression" +""" + +type + Version* = distinct string + Special* = distinct string + + VersionRangeEnum* = enum + verLater, # > V + verEarlier, # < V + verEqLater, # >= V -- Equal or later + verEqEarlier, # <= V -- Equal or earlier + verIntersect, # > V & < V + verEq, # V + verAny, # * + verSpecial # #head + + VersionRange* = ref VersionRangeObj + VersionRangeObj = object + case kind*: VersionRangeEnum + of verLater, verEarlier, verEqLater, verEqEarlier, verEq: + ver*: Version + of verSpecial: + spe*: Special + of verIntersect: + verILeft, verIRight: VersionRange + of verAny: + nil + +proc foo(x: string): VersionRange = + new(result) + result.kind = verEq + result.ver = Version(x) + +proc main = + var a: array[500, VersionRange] + for i in 0 ..< 500: + a[i] = foo($i & "some longer text here " & $i) + GC_fullcollect() + for i in 0 ..< 500: + let expected = $i & "some longer text here " & $i + if a[i].ver.string != expected: + quit "bug!" + echo "done markerproc regression" + +main() diff --git a/tests/ccgbugs/tmissing_ccgtrav_unique_type.nim b/tests/ccgbugs/tmissing_ccgtrav_unique_type.nim new file mode 100644 index 000000000..cb87eabd8 --- /dev/null +++ b/tests/ccgbugs/tmissing_ccgtrav_unique_type.nim @@ -0,0 +1,12 @@ + +# bug #3794 + + +import options + +proc getRef*(): Option[int] = + return none(int) + +proc getChild*() = + let iter = iterator (): int {.closure.} = + let reference = getRef() diff --git a/tests/ccgbugs/tmissingbracket.nim b/tests/ccgbugs/tmissingbracket.nim new file mode 100644 index 000000000..2919efe0e --- /dev/null +++ b/tests/ccgbugs/tmissingbracket.nim @@ -0,0 +1,53 @@ +discard """ +output: ''' +Subobject test called +5 +''' +""" + +type + TClassOfTCustomObject {.pure, inheritable.} = object + base* : ptr TClassOfTCustomObject + className* : string + TClassOfTobj = object of TClassOfTCustomObject + nil + TCustomObject {.inheritable.} = ref object + class* : ptr TClassOfTCustomObject + TObj = ref object of TCustomObject + data: int + +var ClassOfTObj: TClassOfTObj + +proc initClassOfTObj() = + ClassOfTObj.base = nil + ClassOfTObj.className = "TObj" + +initClassOfTObj() + +proc initialize*(self: TObj) = + self.class = addr ClassOfTObj + # this generates wrong C code: && instead of & + +proc newInstance(T: typedesc): T = + mixin initialize + new(result) + initialize(result) + +var o = TObj.newInstance() + +type + TestObj* = object of RootObj + t:int + SubObject* = object of TestObj + +method test*(t:var TestObj) {.base.} = + echo "test called" + +method test*(t:var SubObject) = + echo "Subobject test called" + t.t= 5 + +var a: SubObject + +a.test() +echo a.t diff --git a/tests/ccgbugs/tmissingderef.nim b/tests/ccgbugs/tmissingderef.nim new file mode 100644 index 000000000..eb7da3023 --- /dev/null +++ b/tests/ccgbugs/tmissingderef.nim @@ -0,0 +1,40 @@ +discard """ + output: '''[10, 0, 0, 0, 0, 0, 0, 0] +255 +1 1 +0.5''' +""" + +# bug #1181 + +type + TFoo = object + x: int32 + +proc mainowar = + var foo: TFoo + foo.x = 0xff + var arr1 = cast[ptr array[4, uint8]](addr foo)[] # Fails. + echo arr1[when cpuEndian == littleEndian: 0 else: 3] + + var i = 1i32 + let x = addr i + var arr2 = cast[ptr array[4, uint8]](x)[] # Fails. + echo arr2[when cpuEndian == littleEndian: 0 else: 3], " ", i + + # bug #1715 + var a: array[2, float32] = [0.5'f32, 0.7] + let p = addr a + var b = p[] + echo b[0] + + +# bug 2963 +var + a = [8, 7, 3, 10, 0, 0, 0, 1] + b = [10, 0, 0, 0, 0, 0, 0, 0] + ap = addr a +ap[] = b +echo repr(a) + +mainowar() diff --git a/tests/ccgbugs/tmissingderef2.nim b/tests/ccgbugs/tmissingderef2.nim new file mode 100644 index 000000000..23be61bcb --- /dev/null +++ b/tests/ccgbugs/tmissingderef2.nim @@ -0,0 +1,25 @@ +discard """ + output: "c" +""" + +# bug #5079 + +import tables + +type Test = ref object + s: string + +proc `test=`(t: Test, s: string) = + t.s = s + +var t = Test() + +#t.test = spaces(2) # -- works + +var a = newTable[string, string]() +a["b"] = "c" + +#t.s = a["b"] # -- works +#t.test a["b"] # -- works +t.test = a["b"] # -- prints "out of memory" and quits +echo t.s diff --git a/tests/ccgbugs/tmissinginit.nim b/tests/ccgbugs/tmissinginit.nim new file mode 100644 index 000000000..9eb58221c --- /dev/null +++ b/tests/ccgbugs/tmissinginit.nim @@ -0,0 +1,31 @@ +discard """ + matrix: "--mm:refc" + output: '''0 +0 +0 +0 +[[a = "", +b = []]]''' +""" + +# bug #1475 +type + Crash = object + a: string + b: seq[string] + +proc initCrash(): Crash = discard + +proc test() = + var blongname = [initCrash()] + echo repr(blongname) + +# bug #1434 +proc bug: array[1, int] = discard + +echo bug()[0] +echo bug()[0] +echo bug()[0] +echo bug()[0] + +test() diff --git a/tests/ccgbugs/tmissingvolatile.nim b/tests/ccgbugs/tmissingvolatile.nim new file mode 100644 index 000000000..b877eff71 --- /dev/null +++ b/tests/ccgbugs/tmissingvolatile.nim @@ -0,0 +1,21 @@ +discard """ + output: "1" + cmd: r"nim c --hints:on $options --mm:refc -d:release $file" + ccodecheck: "'NI volatile state;'" + targets: "c" +""" + +# bug #1539 + +proc err() = + raise newException(Exception, "test") + +proc main() = + var state: int + try: + state = 1 + err() + except: + echo state + +main() diff --git a/tests/ccgbugs/tnil_type.nim b/tests/ccgbugs/tnil_type.nim new file mode 100644 index 000000000..9921b24a3 --- /dev/null +++ b/tests/ccgbugs/tnil_type.nim @@ -0,0 +1,15 @@ +discard """ + targets: "c cpp" +""" + +proc f1(v: typeof(nil)) = discard +f1(nil) + +proc f2[T]() = discard +f2[typeof(nil)]() + +proc f3(_: typedesc) = discard +f3(typeof(nil)) + +proc f4[T](_: T) = discard +f4(nil) diff --git a/tests/ccgbugs/tnoalias.nim b/tests/ccgbugs/tnoalias.nim new file mode 100644 index 000000000..2c3c2f0f4 --- /dev/null +++ b/tests/ccgbugs/tnoalias.nim @@ -0,0 +1,13 @@ +discard """ + ccodecheck: "\\i@'NI* NIM_NOALIAS field;' @'NIM_CHAR* NIM_NOALIAS x_p0,' @'void* NIM_NOALIAS q'" +""" + +type + BigNum = object + field {.noalias.}: ptr UncheckedArray[int] + +proc p(x {.noalias.}: openArray[char]) = + var q {.noalias.}: pointer = addr(x[0]) + +var bn: BigNum +p "abc" diff --git a/tests/ccgbugs/tnocodegen_for_compiletime.nim b/tests/ccgbugs/tnocodegen_for_compiletime.nim new file mode 100644 index 000000000..3a952e303 --- /dev/null +++ b/tests/ccgbugs/tnocodegen_for_compiletime.nim @@ -0,0 +1,9 @@ +# bug #1679 +import macros, tables, hashes +proc hash(v: NimNode): Hash = 4 # performance is for suckers +macro test(body: untyped) = + var a = initCountTable[NimNode]() + a.inc(body) + +test: + 1 + 1 diff --git a/tests/ccgbugs/tobjconstr_bad_aliasing.nim b/tests/ccgbugs/tobjconstr_bad_aliasing.nim new file mode 100644 index 000000000..550f9ab75 --- /dev/null +++ b/tests/ccgbugs/tobjconstr_bad_aliasing.nim @@ -0,0 +1,76 @@ +discard """ + output: '''(10, (20, )) +42 +(x: 900.0, y: 900.0) +(x: 900.0, y: 900.0) +(x: 900.0, y: 900.0)''' +""" + +import strutils, sequtils + +# bug #668 + +type + TThing = ref object + data: int + children: seq[TThing] + +proc `$`(t: TThing): string = + result = "($1, $2)" % @[$t.data, join(map(t.children, proc(th: TThing): string = $th), ", ")] + +proc somethingelse(): seq[TThing] = + result = @[TThing(data: 20, children: @[])] + +proc dosomething(): seq[TThing] = + result = somethingelse() + + result = @[TThing(data: 10, children: result)] + +echo($dosomething()[0]) + + +# bug #9844 + +proc f(v: int): int = v + +type X = object + v: int + +var x = X(v: 42) + +x = X(v: f(x.v)) +echo x.v + + +# bug #11525 +type + Point[T] = object + x, y: T + +proc adjustPos[T](width, height: int, pos: Point[T]): Point[T] = + result = pos + + result = Point[T]( + x: pos.x - (width / 2), + y: pos.y - (height / 2) + ) + +proc adjustPos2[T](width, height: int, pos: Point[T]): Point[T] = + result = pos + + result = Point[T]( + x: result.x - (width / 2), + y: result.y - (height / 2) + ) + +proc adjustPos3(width, height: int, pos: Point): Point = + result = pos + + result = Point( + x: result.x - (width / 2), + y: result.y - (height / 2) + ) + +echo adjustPos(200, 200, Point[float](x: 1000, y: 1000)) +echo adjustPos2(200, 200, Point[float](x: 1000, y: 1000)) +echo adjustPos3(200, 200, Point[float](x: 1000, y: 1000)) diff --git a/tests/ccgbugs/tobjconstr_outoforder.nim b/tests/ccgbugs/tobjconstr_outoforder.nim new file mode 100644 index 000000000..846a753d5 --- /dev/null +++ b/tests/ccgbugs/tobjconstr_outoforder.nim @@ -0,0 +1,38 @@ +discard """ + output: '''(left: 1, up: 0, right: 2, down: 0) +(left: 0, up: 1, right: 0, down: 2) +@[(left: 1, up: 0, right: 2, down: 0), (left: 0, up: 1, right: 0, down: 2)] +@[(left: 1, up: 0, right: 2, down: 0), (left: 0, up: 1, right: 0, down: 2)] +true''' +""" + +# bug #5339 +type + Dirs = object + left: int + up: int + right: int + down: int + +let + a = Dirs( + left: 1, + right: 2, + ) + b = Dirs( + up: 1, + down: 2, + ) + works = @[ + a, + b, + ] + fails = @[ + Dirs(left: 1, right: 2), + Dirs(up: 1, down: 2), + ] +echo a +echo b +echo works +echo fails +echo works == fails diff --git a/tests/ccgbugs/tobjconstr_regression.nim b/tests/ccgbugs/tobjconstr_regression.nim new file mode 100644 index 000000000..d29abad97 --- /dev/null +++ b/tests/ccgbugs/tobjconstr_regression.nim @@ -0,0 +1,14 @@ +discard """ + output: '''@[(username: "user", role: "admin", description: "desc", email_addr: "email"), (username: "user", role: "admin", description: "desc", email_addr: "email")]''' +""" + +type + User = object of RootObj + username, role, description, email_addr: string + +# bug 5055 +let us4 = @[ + User(username:"user", role:"admin", description:"desc", email_addr:"email"), + User(username:"user", role:"admin", description:"desc", email_addr:"email"), +] +echo us4 diff --git a/tests/ccgbugs/topenarraycast.nim b/tests/ccgbugs/topenarraycast.nim new file mode 100644 index 000000000..7d1bc8d03 --- /dev/null +++ b/tests/ccgbugs/topenarraycast.nim @@ -0,0 +1,8 @@ +proc foo[T](s: var openArray[T]): T = + for x in s: result += x + +proc bar(xyz: var seq[int]) = + doAssert 6 == (seq[int](xyz)).foo() + +var t = @[1,2,3] +bar(t) diff --git a/tests/ccgbugs/tpartialcs.nim b/tests/ccgbugs/tpartialcs.nim new file mode 100644 index 000000000..12ff65c37 --- /dev/null +++ b/tests/ccgbugs/tpartialcs.nim @@ -0,0 +1,20 @@ + +# bug #2551 + +type Tup = tuple + A, a: int + +type Obj = object + A, a: int + +var x: Tup # This works. +var y: Obj # This doesn't. + +# bug #2212 + +proc f() = + let + p = 1.0 + P = 0.25 + 0.5 + +f() diff --git a/tests/ccgbugs/tprogmem.nim b/tests/ccgbugs/tprogmem.nim new file mode 100644 index 000000000..58a20583a --- /dev/null +++ b/tests/ccgbugs/tprogmem.nim @@ -0,0 +1,11 @@ +discard """ + output: "5" + cmd: r"nim c --hints:on $options -d:release $file" + ccodecheck: "'/*PROGMEM*/ myLetVariable = {'" + targets: "c" +""" + +var myLetVariable {.exportc, codegenDecl: "$# /*PROGMEM*/ $#".} = [1, 2, 3] + +myLetVariable[0] = 5 +echo myLetVariable[0] diff --git a/tests/ccgbugs/trecursive_table.nim b/tests/ccgbugs/trecursive_table.nim new file mode 100644 index 000000000..3406a1c31 --- /dev/null +++ b/tests/ccgbugs/trecursive_table.nim @@ -0,0 +1,17 @@ + +# bug #1700 +import tables + +type + E* = enum + eX + eY + T* = object + case kind: E + of eX: + xVal: Table[string, T] + of eY: + nil + +proc p*(x: Table[string, T]) = + discard diff --git a/tests/ccgbugs/trefseqsort.nim b/tests/ccgbugs/trefseqsort.nim new file mode 100644 index 000000000..2410770cf --- /dev/null +++ b/tests/ccgbugs/trefseqsort.nim @@ -0,0 +1,33 @@ +discard """ + output: '''@[0, 4, 9, 1, 3, 2] +@[0, 1, 2, 3, 9]''' +""" +# bug #6724 +import algorithm + +type + Bar = object + bar: ref seq[int] + Foo = ref Bar + +proc test(x: ref Foo) = + x.bar[].del(1) + x.bar[].sort(cmp) + +proc main() = + var foo: ref Foo + new(foo) + + var s = @[0, 4, 9, 1, 3, 2] + + var sr: ref seq[int] + new(sr) + sr[] = s + + foo[] = Foo(bar: sr) + echo($foo.bar[]) + + test(foo) + echo($foo.bar[]) + +main() diff --git a/tests/ccgbugs/tresult_of_array.nim b/tests/ccgbugs/tresult_of_array.nim new file mode 100644 index 000000000..fb5abf18a --- /dev/null +++ b/tests/ccgbugs/tresult_of_array.nim @@ -0,0 +1,29 @@ +discard """ + output: '''false +true +false +[false, false, false] +''' +""" + +# bug #7332 +# resetLoc generate incorrect memset code +# because of array passed as argument decaying into a pointer + +import tables +const tableOfArray = { + "one": [true, false, false], + "two": [false, true, false], + "three": [false, false, true] +}.toTable() +for i in 0..2: + echo tableOfArray["two"][i] + +var seqOfArray = @[ + [true, false, false], + [false, true, false], + [false, false, true] +] +proc crashingProc*[B](t: seq[B], index: Natural): B = + discard +echo seqOfArray.crashingProc(0) diff --git a/tests/ccgbugs/tret_arg_init.nim b/tests/ccgbugs/tret_arg_init.nim new file mode 100644 index 000000000..e39e5a0de --- /dev/null +++ b/tests/ccgbugs/tret_arg_init.nim @@ -0,0 +1,28 @@ +discard """ + output: ''' + + + +''' +""" + +type Bar = object + s1, s2: string + +proc initBar(): Bar = discard + +var a: array[5, Bar] +a[0].s1 = "hey" +a[0] = initBar() +echo a[0].s1 + +type Foo = object + b: Bar +var f: Foo +f.b.s1 = "hi" +f.b = initBar() +echo f.b.s1 + +var ad = addr f.b +ad[] = initBar() +echo ad[].s1 diff --git a/tests/ccgbugs/tsamename3.nim b/tests/ccgbugs/tsamename3.nim new file mode 100644 index 000000000..ded18e9f8 --- /dev/null +++ b/tests/ccgbugs/tsamename3.nim @@ -0,0 +1,120 @@ +block: # bug #15526 + block: + type Foo = ref object + x1: int + let f1 = Foo(x1: 1) + block: + type Foo = ref object + x2: int + let f2 = Foo(x2: 2) + +block: # ditto + template fn() = + block: + type Foo = ref object + x1: int + let f1 = Foo(x1: 1) + doAssert f1.x1 == 1 + block: + type Foo = ref object + x2: int + let f2 = Foo(x2: 2) + doAssert f2.x2 == 2 + static: fn() + fn() + +block: # bug #17162 + template fn = + var ret: string + block: + type A = enum a0, a1, a2 + for ai in A: + ret.add $ai + block: + type A = enum b0, b1, b2, b3 + for ai in A: + ret.add $ai + doAssert ret == "a0a1a2b0b1b2b3" + + static: fn() # ok + fn() # was bug + +block: # ditto + proc fn = + var ret: string + block: + type A = enum a0, a1, a2 + for ai in A: + ret.add $ai + block: + type A = enum b0, b1, b2, b3 + for ai in A: + ret.add $ai + doAssert ret == "a0a1a2b0b1b2b3" + + static: fn() # ok + fn() # was bug + +block: # bug #5170 + block: + type Foo = object + x1: int + let f1 = Foo(x1: 1) + block: + type Foo = object + x2: int + let f2 = Foo(x2: 2) + +block: # ditto + block: + type Foo = object + bar: bool + var f1: Foo + + block: + type Foo = object + baz: int + var f2: Foo + doAssert f2.baz == 0 + + block: + template fn() = + block: + type Foo = object + x1: int + let f1 = Foo(x1: 1) + doAssert f1.x1 == 1 + block: + type Foo = object + x2: int + let f2 = Foo(x2: 2) + doAssert f2.x2 == 2 + static: fn() + fn() + +when true: # ditto, refs https://github.com/nim-lang/Nim/issues/5170#issuecomment-582712132 + type Foo1 = object # at top level + bar: bool + var f1: Foo1 + + block: + type Foo1 = object + baz: int + var f2: Foo1 + doAssert f2.baz == 0 + +block: # make sure `hashType` doesn't recurse infinitely + type + PFoo = ref object + a, b: PFoo + c: int + var a: PFoo + +block: # issue #22571 + macro foo(x: typed) = + result = x + + block: # or `proc main =` + foo: + type Foo = object + doAssert $Foo() == "()" diff --git a/tests/ccgbugs/tsequence_outoforder.nim b/tests/ccgbugs/tsequence_outoforder.nim new file mode 100644 index 000000000..93a45900d --- /dev/null +++ b/tests/ccgbugs/tsequence_outoforder.nim @@ -0,0 +1,11 @@ +discard """ + output: '''@[2]''' +""" + +# bug #9684 + +var s2 = @[2, 2] + +s2 = @[s2.len] + +echo s2 diff --git a/tests/ccgbugs/tsighash_typename_regression.nim b/tests/ccgbugs/tsighash_typename_regression.nim new file mode 100644 index 000000000..b93eebd20 --- /dev/null +++ b/tests/ccgbugs/tsighash_typename_regression.nim @@ -0,0 +1,32 @@ +discard """ +output: ''' +123 +baz +''' +""" + +# bug #5147 + +proc foo[T](t: T) = + type Wrapper = object + get: T + let w = Wrapper(get: t) + echo w.get + +foo(123) +foo("baz") + +# Empty type in template is correctly disambiguated +block: + template foo() = + type M = object + discard + var y = M() + + foo() + + type M = object + x: int + + var x = M(x: 1) + doAssert(x.x == 1) diff --git a/tests/ccgbugs/tstringslice.nim b/tests/ccgbugs/tstringslice.nim new file mode 100644 index 000000000..0ff448dcf --- /dev/null +++ b/tests/ccgbugs/tstringslice.nim @@ -0,0 +1,20 @@ +discard """ + output: '''1 +1234 +2 +234 +3 +34 +4 +4''' +""" + +# bug #794 +type TRange = range[0..3] + +const str = "123456789" + +for i in TRange.low .. TRange.high: + echo str[i] #This works fine + echo str[int(i) .. int(TRange.high)] #So does this + #echo str[i .. TRange.high] #The compiler complains about this diff --git a/tests/ccgbugs/tunsafeaddr.nim b/tests/ccgbugs/tunsafeaddr.nim new file mode 100644 index 000000000..f868739de --- /dev/null +++ b/tests/ccgbugs/tunsafeaddr.nim @@ -0,0 +1,47 @@ +discard """ + output: '''12 +4''' +""" + +{.emit: """ +NI sum(NI* a, NI len) { + NI i, result = 0; + for (i = 0; i < len; ++i) result += a[i]; + return result; +} +""".} + +proc sum(a: ptr int; len: int): int {.importc, nodecl.} + +proc main = + let foo = [8, 3, 1] + echo sum(unsafeAddr foo[0], foo.len) + + +# bug #3736 + +proc p(x: seq[int]) = discard x[0].unsafeAddr # works +proc q(x: seq[SomeInteger]) = discard x[0].unsafeAddr # doesn't work + +p(@[1]) +q(@[1]) + +main() + +# bug #9403 + +type + MyObj = ref object + len: int + val: UncheckedArray[uint64] + +proc spot(x: MyObj): int64 = + result = cast[UncheckedArray[int64]](x.val)[0] + +proc newMyObj(len: int): MyObj = + unsafeNew(result, sizeof(result[]) + len * sizeof(uint64)) + result.len = len + result.val[0] = 4u64 + result.val[1] = 8u64 + +echo spot(newMyObj(2)) diff --git a/tests/ccgbugs/tuple_canon.nim b/tests/ccgbugs/tuple_canon.nim new file mode 100644 index 000000000..fbb971861 --- /dev/null +++ b/tests/ccgbugs/tuple_canon.nim @@ -0,0 +1,119 @@ +discard """ +output: ''' +vidx 18 +0,0 +''' +""" + +# bug #4626 +var foo: (int, array[1, int]) # Tuple must be of length > 1 +let bar = (1, [1]) +foo = bar # No error if assigned directly + +# bug #2250 + +import math + +type + Meters = float + Point2[T] = tuple[x, y: T] + + HexState* = enum + hsOn, hsOff + + Index = uint16 + + HexGrid* = object + w, h: int ## Width and height of the hex grid. + radius: Meters ## Radius of circle that circumscribes a hexagon. + grid: seq[HexState] ## Information on what hexes are drawn. + + HexVtxIndex = enum + hiA, hiB, hiC, hiD, hiE, hiF + + HexCoord* = Point2[int] + +const + HexDY = sqrt(1.0 - (0.5 * 0.5)) # dy from center to midpoint of 1-2 + HexDX = sqrt(1.0 - (HexDY * HexDY)) # dx from center to midpoint of 1-5 (0.5) + + +let + hexOffsets : array[HexVtxIndex, Point2[float]] = [ + (-1.0, 0.0), + (-HexDX, -HexDY), + (HexDX, -HexDY), + (1.0, 0.0), + (HexDX, HexDY), + (-HexDX, HexDY)] + + evenSharingOffsets : array[HexVtxIndex, tuple[hc: HexCoord; idx: HexVtxIndex]] = [ + ((0,0), hiA), + ((0,0), hiB), + ((1,-1), hiA), + ((1,0), hiB), + ((1,0), hiA), + ((0,1), hiB)] + + oddSharingOffsets : array[HexVtxIndex, tuple[hc: HexCoord; idx: HexVtxIndex]] = [ + ((0,0), hiA), + ((0,0), hiB), + ((1,0), hiA), + ((1,1), hiB), + ((1,1), hiA), + ((0,1), hiB)] + +template odd*(i: int) : untyped = + (i and 1) != 0 + +proc vidx(hg: HexGrid; col, row: int; i: HexVtxIndex) : Index = + #NOTE: this variation compiles + #var offset : typeof(evenSharingOffsets[i]) + # + #if odd(col): + # offset = oddSharingOffsets[i] + #else: + # offset = evenSharingOffsets[i] + + let + #NOTE: this line generates the bad code + offset = (if odd(col): oddSharingOffsets[i] else: evenSharingOffsets[i]) + x = col + 1 + offset.hc.x + y = row + 1 + offset.hc.y + + result = Index(x*2 + y * (hg.w + 2)*2 + int(offset.idx)) + +proc go() = + var hg : HexGrid + + echo "vidx ", $vidx(hg, 1, 2, hiC) + +go() + +# another sighashes problem: In tuples we have to ignore ranges. + +type + Position = tuple[x, y: int16] + n16 = range[0'i16..high(int16)] + +proc print(pos: Position) = + echo $pos.x, ",", $pos.y + +var x = 0.n16 +var y = 0.n16 +print((x, y)) + + +# bug #6889 +proc createProgressSetterWithPropSetter[T](setter: proc(v: T)) = discard + +type A = distinct array[4, float32] +type B = distinct array[3, float32] + +type Foo[T] = tuple + setter: proc(v: T) + +proc getFoo[T](): Foo[T] = discard + +createProgressSetterWithPropSetter(getFoo[A]().setter) +createProgressSetterWithPropSetter(getFoo[B]().setter) diff --git a/tests/ccgbugs/tuplecast.nim b/tests/ccgbugs/tuplecast.nim new file mode 100644 index 000000000..d60e8c490 --- /dev/null +++ b/tests/ccgbugs/tuplecast.nim @@ -0,0 +1,8 @@ + +# bug #4345 + +# only needs to compile +proc f(): tuple[a, b: uint8] = (1'u8, 2'u8) + +let a, b = f() +let c = cast[int](b) diff --git a/tests/ccgbugs/tweakopenarray.nim b/tests/ccgbugs/tweakopenarray.nim new file mode 100644 index 000000000..51d781331 --- /dev/null +++ b/tests/ccgbugs/tweakopenarray.nim @@ -0,0 +1,12 @@ +# bug #4089 + +type + Proc = proc(args: openArray[Bar]): Bar + + Foo = object + p: Proc + + Bar = object + f: Foo + +proc bar(val: Foo): Bar = Bar() diff --git a/tests/ccgbugs/twrong_discriminant_check.nim b/tests/ccgbugs/twrong_discriminant_check.nim new file mode 100644 index 000000000..a802f45ef --- /dev/null +++ b/tests/ccgbugs/twrong_discriminant_check.nim @@ -0,0 +1,30 @@ +discard """ + output: "(kind: None)" +""" + +when true: + # bug #2637 + + type + OptionKind = enum + None, + Some + + Option*[T] = object + case kind: OptionKind + of None: + discard + of Some: + value*: T + + proc none*[T](): Option[T] = + Option[T](kind: None) + + proc none*(T: typedesc): Option[T] = none[T]() + + + proc test(): Option[int] = + int.none + + echo test() + diff --git a/tests/ccgbugs/twrong_method.nim b/tests/ccgbugs/twrong_method.nim new file mode 100644 index 000000000..9879c6114 --- /dev/null +++ b/tests/ccgbugs/twrong_method.nim @@ -0,0 +1,27 @@ +discard """ + cmd: "nim c -d:release $file" + output: '''correct method''' +""" +# bug #5439 +type + Control* = ref object of RootObj + + ControlImpl* = ref object of Control + + Container* = ref object of ControlImpl + + ContainerImpl* = ref object of Container + +method testProc*(control: Control) {.base.} = echo "wrong method" + +method testProc*(container: Container) = echo "correct method" + +proc main() + +main() # wrong method called + +proc main() = + var container = new ContainerImpl + container.testProc() + +# main() # correct method called diff --git a/tests/ccgbugs/twrong_rc_for_refarray.nim b/tests/ccgbugs/twrong_rc_for_refarray.nim new file mode 100644 index 000000000..99bdac5e1 --- /dev/null +++ b/tests/ccgbugs/twrong_rc_for_refarray.nim @@ -0,0 +1,26 @@ +discard """ + output: '''m[0][0] = 1.0 +m[0][0] = 2.0''' +""" +# bug #4653 +type + Vector = ref array[2, float64] + Matrix = ref array[2, Vector] + +proc newVector(): Vector = + new(result) + +proc newMatrix(): Matrix = + new(result) + for ix in 0 .. 1: + result[ix] = newVector() + +let m = newMatrix() + +m[0][0] = 1.0 +echo "m[0][0] = ", m[0][0] + +GC_fullCollect() + +m[0][0] = 2.0 +echo "m[0][0] = ", m[0][0] diff --git a/tests/ccgbugs/twrong_string_asgn.nim b/tests/ccgbugs/twrong_string_asgn.nim new file mode 100644 index 000000000..669b7f8f5 --- /dev/null +++ b/tests/ccgbugs/twrong_string_asgn.nim @@ -0,0 +1,19 @@ +discard """ + output: "adf" +""" + +import asyncdispatch +const + test = ["adf"] + +proc foo() {.async.} = + for i in test: + echo(i) + +var finished = false +let x = foo() +x.callback = + proc () = + finished = true + +while not finished: poll() diff --git a/tests/ccgbugs/twrong_tupleconv.nim b/tests/ccgbugs/twrong_tupleconv.nim new file mode 100644 index 000000000..031712dac --- /dev/null +++ b/tests/ccgbugs/twrong_tupleconv.nim @@ -0,0 +1,35 @@ +discard """ + targets: "c cpp" + matrix: "--gc:refc; --gc:arc" +""" + +# bug #1833 +iterator myitems*[T](a: var seq[T]): var T {.inline.} = + ## iterates over each item of `a` so that you can modify the yielded value. + var i = 0 + let L = len(a) + while i < L: + yield a[i] + inc(i) + doAssert(len(a) == L, "the length of the seq changed while iterating over it") + +# Works fine +var xs = @[1,2,3] +for x in myitems(xs): + inc x + +# Tuples don't work +var ys = @[(1,"a"),(2,"b"),(3,"c")] +for y in myitems(ys): + inc y[0] + +# bug #16331 +type T1 = tuple[a, b: int] + +proc p(b: bool): string = + var x: T1 = (10, 20) + x = if b: (x.b, x.a) else: (-x.b, -x.a) + $x + +assert p(false) == "(a: -20, b: -10)" +assert p(true) == "(a: 20, b: 10)" diff --git a/tests/ccgbugs/twrongrefcounting.nim b/tests/ccgbugs/twrongrefcounting.nim new file mode 100644 index 000000000..8ebaf4058 --- /dev/null +++ b/tests/ccgbugs/twrongrefcounting.nim @@ -0,0 +1,33 @@ +discard """ + output: '''ok''' + cmd: "nim c -r --gc:refc -d:useGcAssert -d:useSysAssert -d:fulldebug -d:smokeCycles $file" +""" + +# bug #9825 +func empty(T: typedesc): T = discard +const emptyChunk = @(empty(array[10, byte])) + +var lst: seq[seq[byte]] +lst.add emptyChunk + +doAssert($lst == "@[@[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]") + + +# bug #6234 +type + Foo = ref object + s: seq[Bar] + Bar = ref object + f: Foo + +proc test() = + var f = Foo.new() + for i in 0 .. 5: + f.s = @[] + for j in 0 .. 5: + var b = Bar.new() + b.f = f + f.s.add(b) + +test() +echo "ok" diff --git a/tests/ccgbugs/xarray9578.nim b/tests/ccgbugs/xarray9578.nim new file mode 100644 index 000000000..849f16821 --- /dev/null +++ b/tests/ccgbugs/xarray9578.nim @@ -0,0 +1,7 @@ +import t9578 + +proc testArray*(x: var array[3,mytype]) = + f(x[0].addr) + +proc testArray2*(x: var ptr array[3,mytype]) = + f(x[0].addr) diff --git a/tests/ccgbugs/xoa9578.nim b/tests/ccgbugs/xoa9578.nim new file mode 100644 index 000000000..94ef34519 --- /dev/null +++ b/tests/ccgbugs/xoa9578.nim @@ -0,0 +1,4 @@ +import t9578 + +proc testOpenArray*(x: var openArray[mytype]) = + f(x[0].addr) diff --git a/tests/ccgbugs/xseq9578.nim b/tests/ccgbugs/xseq9578.nim new file mode 100644 index 000000000..782efe04f --- /dev/null +++ b/tests/ccgbugs/xseq9578.nim @@ -0,0 +1,7 @@ +import t9578 + +proc testSeq*(x: var seq[mytype]) = + f(x[0].addr) + +proc testSeq2*(x: var ptr seq[mytype]) = + f(x[0].addr) diff --git a/tests/ccgbugs/xtuple9578.nim b/tests/ccgbugs/xtuple9578.nim new file mode 100644 index 000000000..b6320fc24 --- /dev/null +++ b/tests/ccgbugs/xtuple9578.nim @@ -0,0 +1,7 @@ +import t9578 + +proc testTuple*(x: var tuple[a:mytype,b:mytype,c:mytype]) = + f(x[0].addr) + +proc testTuple2*(x: var ptr tuple[a:mytype,b:mytype,c:mytype]) = + f(x[0].addr) diff --git a/tests/ccgbugs/xua9578.nim b/tests/ccgbugs/xua9578.nim new file mode 100644 index 000000000..9ba6f8fbc --- /dev/null +++ b/tests/ccgbugs/xua9578.nim @@ -0,0 +1,7 @@ +import t9578 + +proc testUncheckedArray*(x: var UncheckedArray[mytype]) = + f(x[0].addr) + +proc testUncheckedArray2*(x: var ptr UncheckedArray[mytype]) = + f(x[0].addr) |