summary refs log tree commit diff stats
path: root/tests/vm
diff options
context:
space:
mode:
Diffstat (limited to 'tests/vm')
-rw-r--r--tests/vm/mscriptcompiletime.nim7
-rw-r--r--tests/vm/t18103.nim35
-rw-r--r--tests/vm/t19075.nim19
-rw-r--r--tests/vm/t21704.nim69
-rw-r--r--tests/vm/t9622.nim2
-rw-r--r--tests/vm/tcnstseq.nim68
-rw-r--r--tests/vm/tconst.nim10
-rw-r--r--tests/vm/tconstarrayresem.nim29
-rw-r--r--tests/vm/tconstresem.nim10
-rw-r--r--tests/vm/tconstscope1.nim5
-rw-r--r--tests/vm/tconstscope2.nim5
-rw-r--r--tests/vm/tconsttable.nim15
-rw-r--r--tests/vm/tconvaddr.nim49
-rw-r--r--tests/vm/tfibconst.nim43
-rw-r--r--tests/vm/tgenericcompiletimeproc.nim36
-rw-r--r--tests/vm/tmisc_vm.nim12
-rw-r--r--tests/vm/tnilclosurecall.nim8
-rw-r--r--tests/vm/tnilclosurecallstacktrace.nim23
-rw-r--r--tests/vm/tnocompiletimefunc.nim14
-rw-r--r--tests/vm/tnocompiletimefunclambda.nim6
-rw-r--r--tests/vm/tnoreturn.nim32
-rw-r--r--tests/vm/topenarrays.nim20
-rw-r--r--tests/vm/tscriptcompiletime.nims9
-rw-r--r--tests/vm/tsignaturehash.nim2
-rw-r--r--tests/vm/ttouintconv.nim7
-rw-r--r--tests/vm/ttypedesc.nim31
-rw-r--r--tests/vm/tunsupportedintfloatcast.nim3
-rw-r--r--tests/vm/tvmmisc.nim237
-rw-r--r--tests/vm/tvmopsDanger.nim13
29 files changed, 795 insertions, 24 deletions
diff --git a/tests/vm/mscriptcompiletime.nim b/tests/vm/mscriptcompiletime.nim
new file mode 100644
index 000000000..ed7e7c029
--- /dev/null
+++ b/tests/vm/mscriptcompiletime.nim
@@ -0,0 +1,7 @@
+# bug.nim
+var bar* {.compileTime.} = 1
+
+proc dummy = discard
+
+static:
+  inc bar
\ No newline at end of file
diff --git a/tests/vm/t18103.nim b/tests/vm/t18103.nim
new file mode 100644
index 000000000..8622ab290
--- /dev/null
+++ b/tests/vm/t18103.nim
@@ -0,0 +1,35 @@
+discard """
+  targets: "c cpp"
+  matrix: "--mm:refc; --mm:arc"
+"""
+
+import base64, complex, sequtils, math, sugar
+
+type
+
+  FP = float
+  T = object
+    index: int
+    arg: FP
+    val: Complex[FP]
+  M = object
+    alpha, beta: FP
+
+func a(s: openArray[T], model: M): seq[T] =
+  let f = (tn: int) => model.alpha + FP(tn) * model.beta;
+  return mapIt s:
+    block:
+      let s = it.val * rect(1.0, - f(it.index))
+      T(index: it.index, arg: phase(s), val: s)
+
+proc b(): float64 =
+  var s = toSeq(0..10).mapIt(T(index: it, arg: 1.0, val: complex.complex(1.0)))
+  discard a(s, M(alpha: 1, beta: 1))
+  return 1.0
+
+func cc(str: cstring, offset: ptr[cdouble]): cint {.exportc.} =
+  offset[] = b()
+  return 0
+
+static:
+  echo b()
diff --git a/tests/vm/t19075.nim b/tests/vm/t19075.nim
new file mode 100644
index 000000000..89ca9cb19
--- /dev/null
+++ b/tests/vm/t19075.nim
@@ -0,0 +1,19 @@
+discard """
+  timeout: 10
+  joinable: false
+"""
+
+# bug #19075
+const size = 50_000
+
+const stuff = block:
+    var a: array[size, int]
+    a
+
+const zeugs = block:
+    var zeugs: array[size, int]
+    for i in 0..<size:
+        zeugs[i] = stuff[i]
+    zeugs
+
+doAssert zeugs[0] == 0
\ No newline at end of file
diff --git a/tests/vm/t21704.nim b/tests/vm/t21704.nim
new file mode 100644
index 000000000..27f4f5b06
--- /dev/null
+++ b/tests/vm/t21704.nim
@@ -0,0 +1,69 @@
+discard """
+matrix: "--hints:off"
+nimout: '''
+Found 2 tests to run.
+Found 3 benches to compile.
+ 
+  --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow 
+ 
+  --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow 
+ 
+  --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow
+'''
+"""
+# bug #21704
+import std/strformat
+
+const testDesc: seq[string] = @[
+  "tests/t_hash_sha256_vs_openssl.nim",
+  "tests/t_cipher_chacha20.nim"
+]
+const benchDesc = [
+  "bench_sha256",
+  "bench_hash_to_curve",
+  "bench_ethereum_bls_signatures"
+]
+
+proc setupTestCommand(flags, path: string): string =
+  return "nim c -r " &
+    flags &
+    &" --nimcache:nimcache/{path} " & # Commenting this out also solves the issue
+    path
+
+proc testBatch(commands: var string, flags, path: string) =
+  commands &= setupTestCommand(flags, path) & '\n'
+
+proc setupBench(benchName: string): string =
+  var runFlags = if false: " -r "
+                 else: " " # taking this branch is needed to trigger the bug
+
+  echo runFlags # Somehow runflags isn't reset in corner cases
+  runFlags &= " --passC:-Wno-stringop-overflow --passL:-Wno-stringop-overflow "
+  echo runFlags
+
+  return "nim c " &
+       runFlags &
+       &" benchmarks/{benchName}.nim"
+
+proc buildBenchBatch(commands: var string, benchName: string) =
+  let command = setupBench(benchName)
+  commands &= command & '\n'
+
+proc addTestSet(cmdFile: var string) =
+  echo "Found " & $testDesc.len & " tests to run."
+
+  for path in testDesc:
+    var flags = "" # This is important
+    cmdFile.testBatch(flags, path)
+
+proc addBenchSet(cmdFile: var string) =
+  echo "Found " & $benchDesc.len & " benches to compile."
+  for bd in benchDesc:
+    cmdFile.buildBenchBatch(bd)
+
+proc task_bug() =
+  var cmdFile: string
+  cmdFile.addTestSet() # Comment this out and there is no bug
+  cmdFile.addBenchSet()
+
+static: task_bug()
diff --git a/tests/vm/t9622.nim b/tests/vm/t9622.nim
index 214ab0f19..fada8fe59 100644
--- a/tests/vm/t9622.nim
+++ b/tests/vm/t9622.nim
@@ -1,6 +1,6 @@
 discard """
   targets: "c cpp"
-  matrix: "--gc:refc; --gc:arc"
+  matrix: "--mm:refc; --mm:arc"
 """
 
 type
diff --git a/tests/vm/tcnstseq.nim b/tests/vm/tcnstseq.nim
new file mode 100644
index 000000000..5679a6e37
--- /dev/null
+++ b/tests/vm/tcnstseq.nim
@@ -0,0 +1,68 @@
+discard """
+output: '''
+AngelikaAnneAnnaAnkaAnja
+AngelikaAnneAnnaAnkaAnja
+AngelikaAnneAnnaAnkaAnja
+onetwothree
+onetwothree
+onetwothree
+one1two2three3
+'''
+"""
+# Test the new implicit conversion from sequences to arrays in a constant
+# context.
+
+import strutils
+
+
+block t1:
+  const
+    myWords = "Angelika Anne Anna Anka Anja".split()
+
+  for x in items(myWords):
+    write(stdout, x) #OUT AngelikaAnneAnnaAnkaAnja
+  echo ""
+
+
+block t2:
+  const
+    myWords = @["Angelika", "Anne", "Anna", "Anka", "Anja"]
+
+  for i in 0 .. high(myWords):
+    write(stdout, myWords[i]) #OUT AngelikaAnneAnnaAnkaAnja
+  echo ""
+
+
+block t3:
+  for w in items(["Angelika", "Anne", "Anna", "Anka", "Anja"]):
+    write(stdout, w) #OUT AngelikaAnneAnnaAnkaAnja
+  echo ""
+
+
+block t2656:
+  iterator it1(args: seq[string]): string =
+    for s in args: yield s
+  iterator it2(args: seq[string]): string {.closure.} =
+    for s in args: yield s
+  iterator it3(args: openArray[string]): string {.closure.} =
+    for s in args: yield s
+  iterator it4(args: openArray[(string, string)]): string {.closure.} =
+    for s1, s2 in items(args): yield s1 & s2
+
+  block:
+    const myConstSeq = @["one", "two", "three"]
+    for s in it1(myConstSeq):
+      stdout.write s
+    echo ""
+    for s in it2(myConstSeq):
+      stdout.write s
+    echo ""
+    for s in it3(myConstSeq):
+      stdout.write s
+    echo ""
+
+  block:
+    const myConstSeq = @[("one", "1"), ("two", "2"), ("three", "3")]
+    for s in it4(myConstSeq):
+      stdout.write s
+    echo ""
diff --git a/tests/vm/tconst.nim b/tests/vm/tconst.nim
index c2bcf78b5..5cfe7533e 100644
--- a/tests/vm/tconst.nim
+++ b/tests/vm/tconst.nim
@@ -42,6 +42,16 @@ template main() =
       discard (x, increment, a)
     mytemp()
 
+  block: # bug #12334
+    block:
+      const b: cstring = "foo"
+      var c = b
+      doAssert c == "foo"
+    block:
+      const a = "foo"
+      const b: cstring = a
+      var c = b
+      doAssert c == "foo"
 
 
 static: main()
diff --git a/tests/vm/tconstarrayresem.nim b/tests/vm/tconstarrayresem.nim
new file mode 100644
index 000000000..6701cfe4d
--- /dev/null
+++ b/tests/vm/tconstarrayresem.nim
@@ -0,0 +1,29 @@
+# issue #23010
+
+type
+  Result[T, E] = object
+    case oResult: bool
+    of false:
+      discard
+    of true:
+      vResult: T
+
+  Opt[T] = Result[T, void]
+
+template ok[T, E](R: type Result[T, E], x: untyped): R =
+  R(oResult: true, vResult: x)
+
+template c[T](v: T): Opt[T] = Opt[T].ok(v)
+
+type
+  FixedBytes[N: static[int]] = distinct array[N, byte]
+
+  H = object
+    d: FixedBytes[2]
+
+const b = default(H)
+template g(): untyped =
+  const t = default(H)
+  b
+
+discard c(g())
diff --git a/tests/vm/tconstresem.nim b/tests/vm/tconstresem.nim
new file mode 100644
index 000000000..4526cb891
--- /dev/null
+++ b/tests/vm/tconstresem.nim
@@ -0,0 +1,10 @@
+block: # issue #19849
+  type
+    Vec2[T] = object
+      x, y: T
+    Vec2i = Vec2[int]
+  template getX(p: Vec2i): int = p.x
+  let x = getX:
+    const t = Vec2i(x: 1, y: 2)
+    t
+  doAssert x == 1
diff --git a/tests/vm/tconstscope1.nim b/tests/vm/tconstscope1.nim
new file mode 100644
index 000000000..41c45a28f
--- /dev/null
+++ b/tests/vm/tconstscope1.nim
@@ -0,0 +1,5 @@
+# issue #5395
+
+const a = (var b = 3; b)
+echo b #[tt.Error
+     ^ undeclared identifier: 'b']#
diff --git a/tests/vm/tconstscope2.nim b/tests/vm/tconstscope2.nim
new file mode 100644
index 000000000..d858e96c2
--- /dev/null
+++ b/tests/vm/tconstscope2.nim
@@ -0,0 +1,5 @@
+const
+  a = (var x = 3; x)
+  # should we allow this?
+  b = x #[tt.Error
+      ^ undeclared identifier: 'x']#
diff --git a/tests/vm/tconsttable.nim b/tests/vm/tconsttable.nim
index 64a74a59d..152a33cba 100644
--- a/tests/vm/tconsttable.nim
+++ b/tests/vm/tconsttable.nim
@@ -17,3 +17,18 @@ x = "ah"
 echo foo[x]
 x = "possible."
 echo foo[x]
+
+block: # bug #19840
+  const testBytes = [byte 0xD8, 0x08, 0xDF, 0x45, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x61]
+  var tempStr = "__________________"
+
+  tempStr.prepareMutation
+  copyMem(addr tempStr[0], addr testBytes[0], testBytes.len)
+
+block: # bug #22389
+  func foo(): ptr UncheckedArray[byte] =
+    const bar = [77.byte]
+    cast[ptr UncheckedArray[byte]](addr bar[0])
+
+  doAssert foo()[0] == 77
+
diff --git a/tests/vm/tconvaddr.nim b/tests/vm/tconvaddr.nim
new file mode 100644
index 000000000..9762a9e59
--- /dev/null
+++ b/tests/vm/tconvaddr.nim
@@ -0,0 +1,49 @@
+block: # issue #24097
+  type Foo = distinct int
+  proc foo(x: var Foo) =
+    int(x) += 1
+  proc bar(x: var int) =
+    x += 1
+  static:
+    var x = Foo(1)
+    int(x) = int(x) + 1
+    doAssert x.int == 2
+    int(x) += 1
+    doAssert x.int == 3
+    foo(x)
+    doAssert x.int == 4
+    bar(int(x)) # need vmgen flags propagated for this
+    doAssert x.int == 5
+  type Bar = object
+    x: Foo
+  static:
+    var obj = Bar(x: Foo(1))
+    int(obj.x) = int(obj.x) + 1
+    doAssert obj.x.int == 2
+    int(obj.x) += 1
+    doAssert obj.x.int == 3
+    foo(obj.x)
+    doAssert obj.x.int == 4
+    bar(int(obj.x)) # need vmgen flags propagated for this
+    doAssert obj.x.int == 5
+  static:
+    var arr = @[Foo(1)]
+    int(arr[0]) = int(arr[0]) + 1
+    doAssert arr[0].int == 2
+    int(arr[0]) += 1
+    doAssert arr[0].int == 3
+    foo(arr[0])
+    doAssert arr[0].int == 4
+    bar(int(arr[0])) # need vmgen flags propagated for this
+    doAssert arr[0].int == 5
+  proc testResult(): Foo =
+    result = Foo(1)
+    int(result) = int(result) + 1
+    doAssert result.int == 2
+    int(result) += 1
+    doAssert result.int == 3
+    foo(result)
+    doAssert result.int == 4
+    bar(int(result)) # need vmgen flags propagated for this
+    doAssert result.int == 5
+  doAssert testResult().int == 5
diff --git a/tests/vm/tfibconst.nim b/tests/vm/tfibconst.nim
new file mode 100644
index 000000000..cca6dd84f
--- /dev/null
+++ b/tests/vm/tfibconst.nim
@@ -0,0 +1,43 @@
+discard """
+  nimout: '''
+Fibonacci sequence: 0, 1, 1, 2, 3
+Sequence continues: 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610
+'''
+"""
+
+
+import strformat
+
+var fib_n {.compileTime.}: int
+var fib_prev {.compileTime.}: int
+var fib_prev_prev {.compileTime.}: int
+
+proc next_fib(): int {.compileTime.} =
+  let fib = if fib_n < 2:
+    fib_n
+  else:
+    fib_prev_prev + fib_prev
+  inc(fib_n)
+  fib_prev_prev = fib_prev
+  fib_prev = fib
+  fib
+
+const f0 = next_fib()
+const f1 = next_fib()
+const f2 = next_fib()
+const f3 = next_fib()
+const f4 = next_fib()
+
+static:
+  echo fmt"Fibonacci sequence: {f0}, {f1}, {f2}, {f3}, {f4}"
+
+const fib_continues = block:
+  var result = fmt"Sequence continues: "
+  for i in 0..10:
+    if i > 0:
+      add(result, ", ")
+    add(result, $next_fib())
+  result
+
+static:
+  echo fib_continues
\ No newline at end of file
diff --git a/tests/vm/tgenericcompiletimeproc.nim b/tests/vm/tgenericcompiletimeproc.nim
new file mode 100644
index 000000000..08099ebbe
--- /dev/null
+++ b/tests/vm/tgenericcompiletimeproc.nim
@@ -0,0 +1,36 @@
+block: # issue #10753
+  proc foo(x: int): int {.compileTime.} = x
+  const a = foo(123)
+  doAssert foo(123) == a
+
+  proc bar[T](x: T): T {.compileTime.} = x
+  const b = bar(123)
+  doAssert bar(123) == b
+  const c = bar("abc")
+  doAssert bar("abc") == c
+
+block: # issue #22021
+  proc foo(x: static int): int {.compileTime.} = x + 1
+  doAssert foo(123) == 124
+
+block: # issue #19365
+  proc f[T](x: static T): T {.compileTime.} = x + x
+  doAssert f(123) == 246
+  doAssert f(1.0) == 2.0
+
+block:
+  # don't fold compile time procs in typeof
+  proc fail[T](x: T): T {.compileTime.} =
+    doAssert false
+    x
+  doAssert typeof(fail(123)) is typeof(123)
+  proc p(x: int): int = x
+
+  type Foo = typeof(p(fail(123)))
+
+block: # issue #24150, related regression
+  proc w(T: type): T {.compileTime.} = default(ptr T)[]
+  template y(v: auto): auto = typeof(v) is int
+  discard compiles(y(w int))
+  proc s(): int {.compileTime.} = discard
+  discard s()
diff --git a/tests/vm/tmisc_vm.nim b/tests/vm/tmisc_vm.nim
index af09e8871..1ad830b5f 100644
--- a/tests/vm/tmisc_vm.nim
+++ b/tests/vm/tmisc_vm.nim
@@ -445,3 +445,15 @@ static:
         needSecondIdentifier.mgetOrPut(firstPart, @[]).add((name, pattern))
 
     doAssert needSecondIdentifier[0] == @[("aaaa", "bbbb"), ("aaaaa", "bbbbb"), ("aaaaaa", "bbbbbb"), ("aaaaaaa", "bbbbbbb"), ("aaaaaaaa", "bbbbb")]
+
+# bug #17864
+macro transform*(fn: typed) =
+  quote do:
+    `fn`
+
+var map: Table[string, HashSet[string]]
+proc publish*(): void {.transform.} =
+  map["k"] = init_hash_set[string]()
+  map["k"].incl "d"
+
+publish()
diff --git a/tests/vm/tnilclosurecall.nim b/tests/vm/tnilclosurecall.nim
new file mode 100644
index 000000000..449865b9c
--- /dev/null
+++ b/tests/vm/tnilclosurecall.nim
@@ -0,0 +1,8 @@
+discard """
+  errormsg: "attempt to call nil closure"
+  line: 8
+"""
+
+static:
+  let x: proc () = nil
+  x()
diff --git a/tests/vm/tnilclosurecallstacktrace.nim b/tests/vm/tnilclosurecallstacktrace.nim
new file mode 100644
index 000000000..879060e8e
--- /dev/null
+++ b/tests/vm/tnilclosurecallstacktrace.nim
@@ -0,0 +1,23 @@
+discard """
+  action: reject
+  nimout: '''
+stack trace: (most recent call last)
+tnilclosurecallstacktrace.nim(23, 6) tnilclosurecallstacktrace
+tnilclosurecallstacktrace.nim(20, 6) baz
+tnilclosurecallstacktrace.nim(17, 6) bar
+tnilclosurecallstacktrace.nim(14, 4) foo
+tnilclosurecallstacktrace.nim(14, 4) Error: attempt to call nil closure
+'''
+"""
+
+proc foo(x: proc ()) =
+  x()
+
+proc bar(x: proc ()) =
+  foo(x)
+
+proc baz(x: proc ()) =
+  bar(x)
+
+static:
+  baz(nil)
diff --git a/tests/vm/tnocompiletimefunc.nim b/tests/vm/tnocompiletimefunc.nim
new file mode 100644
index 000000000..a95648c0f
--- /dev/null
+++ b/tests/vm/tnocompiletimefunc.nim
@@ -0,0 +1,14 @@
+discard """
+  errormsg: "request to generate code for .compileTime proc: foo"
+"""
+
+# ensure compileTime funcs can't be called from runtime
+
+func foo(a: int): int {.compileTime.} =
+  a * a
+
+proc doAThing(): int =
+  for i in 0..2:
+    result += foo(i)
+
+echo doAThing()
diff --git a/tests/vm/tnocompiletimefunclambda.nim b/tests/vm/tnocompiletimefunclambda.nim
new file mode 100644
index 000000000..d134eea40
--- /dev/null
+++ b/tests/vm/tnocompiletimefunclambda.nim
@@ -0,0 +1,6 @@
+discard """
+  errormsg: "request to generate code for .compileTime proc: :anonymous"
+"""
+
+let a = func(a: varargs[int]) {.compileTime, closure.} =
+  discard a[0]
\ No newline at end of file
diff --git a/tests/vm/tnoreturn.nim b/tests/vm/tnoreturn.nim
new file mode 100644
index 000000000..d4f8601a9
--- /dev/null
+++ b/tests/vm/tnoreturn.nim
@@ -0,0 +1,32 @@
+block: # issue #22216
+  type
+    Result[T, E] = object
+      case oVal: bool
+      of false:
+        eVal: E
+      of true:
+        vVal: T
+
+  func raiseResultDefect(m: string) {.noreturn, noinline.} =
+    raise (ref Defect)(msg: m)
+
+  template withAssertOk(self: Result, body: untyped): untyped =
+    case self.oVal
+    of false:
+      raiseResultDefect("Trying to access value with err Result")    
+    else:
+      body
+
+  func value[T, E](self: Result[T, E]): T {.inline.} =    
+    withAssertOk(self):  
+      self.vVal
+      
+  const
+    x = Result[int, string](oVal: true, vVal: 123)
+    z = x.value()
+    
+  let
+    xx = Result[int, string](oVal: true, vVal: 123)
+    zz = x.value()
+  
+  doAssert z == zz
diff --git a/tests/vm/topenarrays.nim b/tests/vm/topenarrays.nim
index 0a822f583..375d2523d 100644
--- a/tests/vm/topenarrays.nim
+++ b/tests/vm/topenarrays.nim
@@ -67,3 +67,23 @@ template fn=
   doAssert test([0,1,2,3,4,5]).id == 0
 fn() # ok
 static: fn()
+
+
+block: # bug #22095
+  type
+    StUint = object
+      limbs: array[4, uint64]
+
+  func shlAddMod(a: var openArray[uint64]) =  
+    a[0] = 10
+
+  func divRem(r: var openArray[uint64]) =
+    shlAddMod(r.toOpenArray(0, 3))
+
+  func fn(): StUint =
+    divRem(result.limbs)
+
+  const
+    z = fn()
+
+  doAssert z.limbs[0] == 10
diff --git a/tests/vm/tscriptcompiletime.nims b/tests/vm/tscriptcompiletime.nims
new file mode 100644
index 000000000..daec54bf7
--- /dev/null
+++ b/tests/vm/tscriptcompiletime.nims
@@ -0,0 +1,9 @@
+discard """
+  cmd: "nim e $file"
+"""
+
+import mscriptcompiletime
+
+macro foo =
+  doAssert bar == 2
+foo()
diff --git a/tests/vm/tsignaturehash.nim b/tests/vm/tsignaturehash.nim
index 42e0a1571..972ec6fb0 100644
--- a/tests/vm/tsignaturehash.nim
+++ b/tests/vm/tsignaturehash.nim
@@ -1,7 +1,7 @@
 # test sym digest is computable at compile time
 
 import macros, algorithm
-import md5
+import ../../dist/checksums/src/checksums/md5
 
 macro testmacro(s: typed{nkSym}): string =
   let s = getMD5(signaturehash(s) & " - " & symBodyHash(s))
diff --git a/tests/vm/ttouintconv.nim b/tests/vm/ttouintconv.nim
index ff2187a36..8c43a3adb 100644
--- a/tests/vm/ttouintconv.nim
+++ b/tests/vm/ttouintconv.nim
@@ -75,3 +75,10 @@ macro foo2() =
 
 foo()
 foo2()
+
+block:
+  const neg5VM = block:
+    let x = -5'i8
+    uint64(x)
+  let y = -5'i8
+  doAssert uint64(y) == neg5VM
diff --git a/tests/vm/ttypedesc.nim b/tests/vm/ttypedesc.nim
new file mode 100644
index 000000000..d799e5adb
--- /dev/null
+++ b/tests/vm/ttypedesc.nim
@@ -0,0 +1,31 @@
+block: # issue #15760
+  type
+    Banana = object
+    SpecialBanana = object
+    
+  proc getName(_: type Banana): string = "Banana"
+  proc getName(_: type SpecialBanana): string = "SpecialBanana"
+
+  proc x[T](): string = 
+    const n = getName(T) # this one works
+    result = n
+    
+  proc y(T: type): string =
+    const n = getName(T) # this one failed to compile
+    result = n
+
+  doAssert x[SpecialBanana]() == "SpecialBanana"
+  doAssert y(SpecialBanana) == "SpecialBanana"
+
+import macros
+
+block: # issue #23112
+  type Container = object
+    foo: string
+
+  proc canBeImplicit(t: typedesc) {.compileTime.} =
+    let tDesc = getType(t)
+    doAssert tDesc.kind == nnkObjectTy
+
+  static:
+    canBeImplicit(Container)
diff --git a/tests/vm/tunsupportedintfloatcast.nim b/tests/vm/tunsupportedintfloatcast.nim
new file mode 100644
index 000000000..d65f10d86
--- /dev/null
+++ b/tests/vm/tunsupportedintfloatcast.nim
@@ -0,0 +1,3 @@
+static:
+  echo cast[int32](12.0) #[tt.Error
+       ^ VM does not support 'cast' from tyFloat with size 8 to tyInt32 with size 4 due to different sizes]#
diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim
index 2ce4703b0..6aeac5529 100644
--- a/tests/vm/tvmmisc.nim
+++ b/tests/vm/tvmmisc.nim
@@ -1,7 +1,7 @@
-# bug #4462
 import macros
 import os
 
+# bug #4462
 block:
   proc foo(t: typedesc) {.compileTime.} =
     assert sameType(getType(t), getType(int))
@@ -16,7 +16,7 @@ block:
   static:
     var x = default(type(0))
 
-# #6379
+# bug #6379
 import algorithm
 
 static:
@@ -28,7 +28,7 @@ static:
   str.sort(cmp)
   doAssert str == "abc"
 
-# #6086
+# bug #6086
 import math, sequtils, sugar
 
 block:
@@ -82,8 +82,10 @@ block:
 
     doAssert fileExists("MISSINGFILE") == false
     doAssert dirExists("MISSINGDIR") == false
+    doAssert fileExists(currentSourcePath())
+    doAssert dirExists(currentSourcePath().parentDir)
 
-# #7210
+# bug #7210
 block:
   static:
     proc f(size: int): int =
@@ -91,7 +93,7 @@ block:
       result = size
     doAssert f(4) == 4
 
-# #6689
+# bug #6689
 block:
   static:
     proc foo(): int = 0
@@ -106,7 +108,7 @@ block:
     new(x)
     doAssert(not x.isNil)
 
-# #7871
+# bug #7871
 static:
   type Obj = object
     field: int
@@ -116,11 +118,11 @@ static:
   o.field = 2
   doAssert s[0].field == 0
 
-# #8125
+# bug #8125
 static:
    let def_iter_var = ident("it")
 
-# #8142
+# bug #8142
 static:
   type Obj = object
     names: string
@@ -136,7 +138,7 @@ static:
   o.pushName()
   doAssert o.names == "FOOBARFOOBAR"
 
-# #8154
+# bug #8154
 import parseutils
 
 static:
@@ -149,7 +151,7 @@ static:
   static:
     doAssert foo().i == 1
 
-# #10333
+# bug #10333
 block:
   const
     encoding: auto = [
@@ -160,7 +162,7 @@ block:
     ]
   doAssert encoding.len == 4
 
-# #10886
+# bug #10886
 
 proc tor(): bool =
   result = true
@@ -229,6 +231,14 @@ block: # bug #15595
   static: main()
   main()
 
+block: # issue #20543
+  type F = proc()
+  const myArray = block:
+    var r: array[1, F]
+    r[0] = nil
+    r
+  doAssert isNil(myArray[0])
+
 # bug #15363
 import sequtils
 
@@ -291,14 +301,6 @@ block: # bug #10815
   const a = P()
   doAssert $a == ""
 
-when defined osx: # xxx bug https://github.com/nim-lang/Nim/issues/10815#issuecomment-476380734
-  block:
-    type CharSet {.union.} = object
-      cs: set[char]
-      vs: array[4, uint64]
-    const a = Charset(cs: {'a'..'z'})
-    doAssert a.repr.len > 0
-
 import tables
 
 block: # bug #8007
@@ -353,7 +355,7 @@ block: # bug #8007
 block: # bug #14340
   block:
     proc opl3EnvelopeCalcSin0() = discard
-    type EnvelopeSinfunc = proc()
+    type EnvelopeSinfunc = proc() {.nimcall.} # todo: fixme 
     # const EnvelopeCalcSin0 = opl3EnvelopeCalcSin0 # ok
     const EnvelopeCalcSin0: EnvelopeSinfunc = opl3EnvelopeCalcSin0 # was bug
     const envelopeSin = [EnvelopeCalcSin0]
@@ -564,14 +566,14 @@ block:
 block:
   static:
     let x = int 1
-    echo x.type   # Foo
+    doAssert $(x.type) == "int"  # Foo
 
 block:
   static:
     let x = int 1
     let y = x + 1
     # Error: unhandled exception: value out of range: -8 notin 0 .. 65535 [RangeDefect]
-    echo y
+    doAssert y == 2
 
 
 type Atom* = object
@@ -601,3 +603,194 @@ proc foo(s: sink string) = doAssert s.len == 3
 
 static:
   foo("abc")
+
+
+static:
+  for i in '1' .. '2': # bug #10938
+    var s: set[char]
+    doAssert s == {}
+    incl(s, i)
+
+  for _ in 0 ..< 3: # bug #13312
+    var s: string
+    s.add("foo")
+    doAssert s == "foo"
+
+  for i in 1 .. 5: # bug #13918
+    var arr: array[3, int]
+    var val: int
+    doAssert arr == [0, 0, 0] and val == 0
+    for j in 0 ..< len(arr):
+      arr[j] = i
+      val = i
+
+# bug #20985
+let a = block:
+  var groups: seq[seq[int]]
+  for i in 0 ..< 3:
+    var group: seq[int]
+    for j in 0 ..< 3:
+      group.add j
+    groups.add group
+  groups
+
+const b = block:
+  var groups: seq[seq[int]]
+  for i in 0 ..< 3:
+    var group: seq[int]
+    for j in 0 ..< 3:
+      group.add j
+    groups.add group
+  groups
+
+doAssert a == @[@[0, 1, 2], @[0, 1, 2], @[0, 1, 2]]
+doAssert b == @[@[0, 1, 2], @[0, 1, 2], @[0, 1, 2]]
+
+macro m1(s: string): int =
+  var ProcID {.global, compileTime.}: int
+  inc(ProcID)
+  result = newLit(ProcID)
+
+proc macroGlobal =
+  doAssert m1("Macro argument") == 1
+  doAssert m1("Macro argument") == 2
+  doAssert m1("Macro argument") == 3
+
+static: macroGlobal()
+macroGlobal()
+
+block: # bug #10108
+  template reject(x) =
+    static: doAssert(not compiles(x))
+
+  static:
+    let x: int = 2
+    proc deliver_x(): int = x
+    var y2 = deliver_x()
+    discard y2
+    reject:
+      const c5 = deliver_x()
+
+block: # bug #7590
+  proc doInit[T]():auto=
+    var a: T
+    return a
+
+  proc fun2[T](tup1:T)=
+    const tup0=doInit[T]()
+
+    # var tup=tup0 #ok
+    const tup=tup0 #causes bug
+
+    doAssert tup is tuple
+    doAssert tup[0] is tuple
+    for ai in tup.fields:
+      doAssert ai is tuple, "BUG2"
+
+  # const c=(foo:(bar1: 0.0))
+  const c=(foo:(bar1:"foo1"))
+  fun2(c)
+
+block: # bug #21708
+  type
+    Tup = tuple[name: string]
+
+  const X: array[2, Tup] = [(name: "foo",), (name: "bar",)]
+
+  static:
+    let s = X[0]
+    doAssert s[0] == "foo"
+
+block:
+  proc swap[T](x: var T): T =
+    result = x
+    x = default(T)
+
+  proc merge[T](a, b: var openArray[T]) =
+    a[0] = swap b[0]
+
+  static:
+    var x = "abc"
+    var y = "356"
+    merge(x, y)
+    doAssert x == "3bc"
+
+block: # bug #22190
+  type
+    EVMFork = enum
+      Berlin
+      Istanbul
+      Shanghai
+
+  const
+    Vm2OpAllForks =
+      {EVMFork.low .. EVMFork.high}
+
+    vm2OpExecBlockData = [(forks: Vm2OpAllForks)]
+
+  proc mkOpTable(selected: EVMFork): bool =
+    selected notin vm2OpExecBlockData[0].forks
+
+  const
+    tab = mkOpTable(Berlin)
+
+  doAssert not tab
+
+block: # issue #22524
+  const cnst = cstring(nil)
+  doAssert cnst.isNil
+  doAssert cnst == nil
+  let b = cnst
+  doAssert b.isNil
+  doAssert b == nil
+
+  let a = static: cstring(nil)
+  doAssert a.isNil
+
+  static:
+    var x: cstring
+    doAssert x.isNil
+    doAssert x == nil
+    doAssert x != ""
+
+block: # issue #15730
+  const s: cstring = ""
+  doAssert s != nil
+
+  static:
+    let s: cstring = ""
+    doAssert not s.isNil
+    doAssert s != nil
+    doAssert s == ""
+
+static: # more nil cstring issues
+  let x = cstring(nil)
+  doAssert x.len == 0
+
+block: # bug #23925
+  type Foo = enum A = -1
+  proc foo =
+    doAssert cast[Foo](-1) == A
+    doAssert ord(A) == -1
+
+  static: foo()
+  foo()
+
+  type E = enum
+    e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 e10 e11 e12 e13 e14 e15 e16 e17 e18 e19 e20
+    e21 e22 e23 e24 e25 e26 e27 e28 e29 e30 e31 e32 e33 e34 e35 e36 e37 e38
+    e39 e40 e41 e42 e43 e44 e45 e46 e47 e48 e49 e50 e51 e52 e53 e54 e55 e56
+    e57 e58 e59 e60 e61 e62 e63 e64 e65 e66 e67 e68 e69 e70 e71 e72 e73 e74
+    e75 e76 e77 e78 e79 e80 e81 e82 e83 e84 e85 e86 e87 e88 e89 e90 e91 e92
+    e93 e94 e95 e96 e97 e98 e99 e100 e101 e102 e103 e104 e105 e106 e107 e108
+    e109 e110 e111 e112 e113 e114 e115 e116 e117 e118 e119 e120 e121 e122
+    e123 e124 e125 e126 e127 e128
+  proc bar =
+    doAssert cast[E](int(e128)) == e128
+
+  static: bar()
+  bar()
+
+static: # bug #21353
+  var s: proc () = default(proc ())
+  doAssert s == nil
diff --git a/tests/vm/tvmopsDanger.nim b/tests/vm/tvmopsDanger.nim
new file mode 100644
index 000000000..966feffe6
--- /dev/null
+++ b/tests/vm/tvmopsDanger.nim
@@ -0,0 +1,13 @@
+discard """
+  cmd: "nim c --experimental:vmopsDanger -r $file"
+"""
+when defined(nimPreviewSlimSystem):
+  import std/assertions
+import std/[times, os]
+
+const foo = getTime()
+let bar = foo
+doAssert bar > low(Time)
+
+static: # bug #23932
+  doAssert getCurrentDir().len > 0