summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2019-09-02 22:03:10 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-09-02 22:03:10 +0200
commitac6fcab7a4fc79ba0ca45f531ad5f4f213e9d4e7 (patch)
tree54f03ebd8539f4562d4e2f077d67812aea854889
parentd70e292571754f1c00baf9651c558378537cdba8 (diff)
parent5a03eea518ba3cfeaa9f57ef0b6f1cf7bc8ed1d9 (diff)
downloadNim-ac6fcab7a4fc79ba0ca45f531ad5f4f213e9d4e7.tar.gz
Merge branch 'devel' into uint-range-checks
-rw-r--r--compiler/ast.nim6
-rw-r--r--compiler/astalgo.nim42
-rw-r--r--compiler/ccgexprs.nim7
-rw-r--r--compiler/guards.nim4
-rw-r--r--compiler/jsgen.nim6
-rw-r--r--compiler/parampatterns.nim6
-rw-r--r--compiler/semfold.nim7
-rw-r--r--compiler/semtempl.nim1
-rw-r--r--compiler/sigmatch.nim13
-rw-r--r--compiler/types.nim2
-rw-r--r--compiler/vmgen.nim2
-rw-r--r--lib/pure/nimprof.nim3
-rw-r--r--lib/system.nim22
-rw-r--r--tests/ccgbugs/tnil_type.nim3
-rw-r--r--tests/destructor/tnewruntime_misc.nim13
-rw-r--r--tests/range/trange.nim6
-rw-r--r--tests/system/tsystem_misc.nim12
-rw-r--r--tests/template/tparams_gensymed.nim19
18 files changed, 123 insertions, 51 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 71d19be30..db0321f6c 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -608,7 +608,6 @@ type
     mAddF64, mSubF64, mMulF64, mDivF64,
     mShrI, mShlI, mAshrI, mBitandI, mBitorI, mBitxorI,
     mMinI, mMaxI,
-    mMinF64, mMaxF64,
     mAddU, mSubU, mMulU, mDivU, mModU,
     mEqI, mLeI, mLtI,
     mEqF64, mLeF64, mLtF64,
@@ -621,7 +620,7 @@ type
     mXor, mEqCString, mEqProc,
     mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot,
     mUnaryPlusI, mBitnotI,
-    mUnaryPlusF64, mUnaryMinusF64, mAbsF64,
+    mUnaryPlusF64, mUnaryMinusF64,
     mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr,
     mStrToStr, mEnumToStr,
     mAnd, mOr,
@@ -678,7 +677,6 @@ const
     mAddF64, mSubF64, mMulF64, mDivF64,
     mShrI, mShlI, mBitandI, mBitorI, mBitxorI,
     mMinI, mMaxI,
-    mMinF64, mMaxF64,
     mAddU, mSubU, mMulU, mDivU, mModU,
     mEqI, mLeI, mLtI,
     mEqF64, mLeF64, mLtF64,
@@ -689,7 +687,7 @@ const
     mEqB, mLeB, mLtB,
     mEqRef, mEqProc, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor,
     mUnaryMinusI, mUnaryMinusI64, mAbsI, mNot, mUnaryPlusI, mBitnotI,
-    mUnaryPlusF64, mUnaryMinusF64, mAbsF64,
+    mUnaryPlusF64, mUnaryMinusF64,
     mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr,
     mStrToStr, mEnumToStr,
     mAnd, mOr,
diff --git a/compiler/astalgo.nim b/compiler/astalgo.nim
index 632f00f4d..06611313c 100644
--- a/compiler/astalgo.nim
+++ b/compiler/astalgo.nim
@@ -77,7 +77,6 @@ proc idNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode)
 
 # ---------------------------------------------------------------------------
 
-proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym
 proc lookupInRecord*(n: PNode, field: PIdent): PSym
 proc mustRehash*(length, counter: int): bool
 proc nextTry*(h, maxHash: Hash): Hash {.inline.}
@@ -174,7 +173,7 @@ proc getModule*(s: PSym): PSym =
   assert((result.kind == skModule) or (result.owner != result))
   while result != nil and result.kind != skModule: result = result.owner
 
-proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
+proc getSymFromList*(list: PNode, ident: PIdent, start: int = 0): PSym =
   for i in start ..< sonsLen(list):
     if list.sons[i].kind == nkSym:
       result = list.sons[i].sym
@@ -182,6 +181,45 @@ proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
     else: return nil
   result = nil
 
+proc sameIgnoreBacktickGensymInfo(a, b: string): bool =
+  if a[0] != b[0]: return false
+  var last = a.len - 1
+  while last > 0 and a[last] != '`': dec(last)
+
+  var i = 1
+  var j = 1
+  while true:
+    while i < last and a[i] == '_': inc i
+    while j < b.len and b[j] == '_': inc j
+    var aa = if i < last: toLowerAscii(a[i]) else: '\0'
+    var bb = if j < b.len: toLowerAscii(b[j]) else: '\0'
+    if aa != bb: return false
+
+    # the characters are identical:
+    if i >= last:
+      # both cursors at the end:
+      if j >= b.len: return true
+      # not yet at the end of 'b':
+      return false
+    elif j >= b.len:
+      return false
+    inc i
+    inc j
+
+proc getNamedParamFromList*(list: PNode, ident: PIdent): PSym =
+  ## Named parameters are special because a named parameter can be
+  ## gensym'ed and then they have '`<number>' suffix that we need to
+  ## ignore, see compiler / evaltempl.nim, snippet:
+  ##
+  ## .. code-block:: nim
+  ##
+  ##    result.add newIdentNode(getIdent(c.ic, x.name.s & "`gensym" & $x.id),
+  ##            if c.instLines: actual.info else: templ.info)
+  for i in 1 ..< len(list):
+    let it = list[i].sym
+    if it.name.id == ident.id or
+        sameIgnoreBacktickGensymInfo(it.name.s, ident.s): return it
+
 proc hashNode(p: RootRef): Hash =
   result = hash(cast[pointer](p))
 
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 0ab592a50..0902e2e19 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -588,8 +588,6 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mBitxorI: applyFormat("($4)($1 ^ $2)")
   of mMinI: applyFormat("(($1 <= $2) ? $1 : $2)")
   of mMaxI: applyFormat("(($1 >= $2) ? $1 : $2)")
-  of mMinF64: applyFormat("(($1 <= $2) ? $1 : $2)")
-  of mMaxF64: applyFormat("(($1 >= $2) ? $1 : $2)")
   of mAddU: applyFormat("($4)((NU$3)($1) + (NU$3)($2))")
   of mSubU: applyFormat("($4)((NU$3)($1) - (NU$3)($2))")
   of mMulU: applyFormat("($4)((NU$3)($1) * (NU$3)($2))")
@@ -663,9 +661,6 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
     applyFormat("$1")
   of mUnaryMinusF64:
     applyFormat("-($1)")
-  of mAbsF64:
-    applyFormat("($1 < 0? -($1) : ($1))")
-    # BUGFIX: fabs() makes problems for Tiny C
   else:
     assert false, $op
 
@@ -2086,7 +2081,7 @@ proc genEnumToStr(p: BProc, e: PNode, d: var TLoc) =
 proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   case op
   of mOr, mAnd: genAndOr(p, e, d, op)
-  of mNot..mAbsF64: unaryArith(p, e, d, op)
+  of mNot..mUnaryMinusF64: unaryArith(p, e, d, op)
   of mUnaryMinusI..mAbsI: unaryArithOverflow(p, e, d, op)
   of mAddF64..mDivF64: binaryFloatArith(p, e, d, op)
   of mShrI..mXor: binaryArith(p, e, d, op)
diff --git a/compiler/guards.nim b/compiler/guards.nim
index 1ab50b8b6..be23c1598 100644
--- a/compiler/guards.nim
+++ b/compiler/guards.nim
@@ -35,8 +35,8 @@ const
   someMul = {mMulI, mMulF64}
   someDiv = {mDivI, mDivF64}
   someMod = {mModI}
-  someMax = {mMaxI, mMaxF64}
-  someMin = {mMinI, mMinF64}
+  someMax = {mMaxI}
+  someMin = {mMinI}
   someBinaryOp = someAdd+someSub+someMul+someMax+someMin
 
 proc isValue(n: PNode): bool = n.kind in {nkCharLit..nkNilLit}
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 1d980ab6f..78373ea47 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -389,8 +389,6 @@ const # magic checked op; magic unchecked op;
     ["", ""], # BitxorI
     ["nimMin", "nimMin"], # MinI
     ["nimMax", "nimMax"], # MaxI
-    ["nimMin", "nimMin"], # MinF64
-    ["nimMax", "nimMax"], # MaxF64
     ["", ""], # addU
     ["", ""], # subU
     ["", ""], # mulU
@@ -430,7 +428,6 @@ const # magic checked op; magic unchecked op;
     ["", ""], # BitnotI
     ["", ""], # UnaryPlusF64
     ["", ""], # UnaryMinusF64
-    ["", ""], # AbsF64
     ["nimCharToStr", "nimCharToStr"],
     ["nimBoolToStr", "nimBoolToStr"],
     ["cstrToNimstr", "cstrToNimstr"],
@@ -566,8 +563,6 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
   of mBitxorI: applyFormat("($1 ^ $2)", "($1 ^ $2)")
   of mMinI: applyFormat("nimMin($1, $2)", "nimMin($1, $2)")
   of mMaxI: applyFormat("nimMax($1, $2)", "nimMax($1, $2)")
-  of mMinF64: applyFormat("nimMin($1, $2)", "nimMin($1, $2)")
-  of mMaxF64: applyFormat("nimMax($1, $2)", "nimMax($1, $2)")
   of mAddU: applyFormat("", "")
   of mSubU: applyFormat("", "")
   of mMulU: applyFormat("", "")
@@ -607,7 +602,6 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
   of mBitnotI: applyFormat("~($1)", "~($1)")
   of mUnaryPlusF64: applyFormat("+($1)", "+($1)")
   of mUnaryMinusF64: applyFormat("-($1)", "-($1)")
-  of mAbsF64: applyFormat("Math.abs($1)", "Math.abs($1)")
   of mCharToStr: applyFormat("nimCharToStr($1)", "nimCharToStr($1)")
   of mBoolToStr: applyFormat("nimBoolToStr($1)", "nimBoolToStr($1)")
   of mIntToStr: applyFormat("cstrToNimstr(($1)+\"\")", "cstrToNimstr(($1)+\"\")")
diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim
index 1bd703fe8..b8f1fd832 100644
--- a/compiler/parampatterns.nim
+++ b/compiler/parampatterns.nim
@@ -224,14 +224,14 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
         result = arLocalLValue
       else:
         result = arLValue
-    elif n.sym.kind == skParam and n.sym.typ.kind == tyVar:
+    elif n.sym.kind == skParam and n.sym.typ.kind in {tyVar, tySink}:
       result = arLValue
     elif n.sym.kind == skType:
       let t = n.sym.typ.skipTypes({tyTypeDesc})
       if t.kind == tyVar: result = arStrange
   of nkDotExpr:
     let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc})
-    if t.kind in {tyVar, tyPtr, tyRef}:
+    if t.kind in {tyVar, tySink, tyPtr, tyRef}:
       result = arLValue
     elif isUnsafeAddr and t.kind == tyLent:
       result = arLValue
@@ -242,7 +242,7 @@ proc isAssignable*(owner: PSym, n: PNode; isUnsafeAddr=false): TAssignableResult
       result = arDiscriminant
   of nkBracketExpr:
     let t = skipTypes(n.sons[0].typ, abstractInst-{tyTypeDesc})
-    if t.kind in {tyVar, tyPtr, tyRef}:
+    if t.kind in {tyVar, tySink, tyPtr, tyRef}:
       result = arLValue
     elif isUnsafeAddr and t.kind == tyLent:
       result = arLValue
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index cf1586144..81efc2436 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -197,7 +197,6 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
       result = newIntNodeT(toInt128(sonsLen(a)), n, g)
   of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
   # XXX: Hides overflow/underflow
-  of mAbsF64: result = newFloatNodeT(abs(getFloat(a)), n, g)
   of mAbsI: result = foldAbs(getInt(a), n, g)
   of mUnaryLt: result = foldSub(getOrdValue(a), One, n, g)
   of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, g)
@@ -277,12 +276,6 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
   of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n, g)
   of mDivF64:
     result = newFloatNodeT(getFloat(a) / getFloat(b), n, g)
-  of mMaxF64:
-    if getFloat(a) > getFloat(b): result = newFloatNodeT(getFloat(a), n, g)
-    else: result = newFloatNodeT(getFloat(b), n, g)
-  of mMinF64:
-    if getFloat(a) > getFloat(b): result = newFloatNodeT(getFloat(b), n, g)
-    else: result = newFloatNodeT(getFloat(a), n, g)
   of mIsNil: result = newIntNodeT(ord(a.kind == nkNilLit), n, g)
   of mLtI, mLtB, mLtEnum, mLtCh:
     result = newIntNodeT(ord(getOrdValue(a) < getOrdValue(b)), n, g)
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index 907d2174e..acf32d1b3 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -80,6 +80,7 @@ proc symChoice(c: PContext, n: PNode, s: PSym, r: TSymChoiceRule;
     while a != nil:
       if a.kind != skModule and (not isField or sfGenSym notin s.flags):
         incl(a.flags, sfUsed)
+        markOwnerModuleAsUsed(c, a)
         addSon(result, newSymNode(a, info))
         onUse(info, a)
       a = nextOverloadIter(o, c, n)
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index d30703943..2c22620da 100644
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -108,6 +108,7 @@ const
   isNilConversion = isConvertible # maybe 'isIntConv' fits better?
 
 proc markUsed*(c: PContext; info: TLineInfo, s: PSym)
+proc markOwnerModuleAsUsed*(c: PContext; s: PSym)
 
 template hasFauxMatch*(c: TCandidate): bool = c.fauxMatch != tyNone
 
@@ -380,7 +381,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
         isIntLit(ab) and getInt(ab.n) >= firstOrd(nil, f) and
                          getInt(ab.n) <= lastOrd(nil, f):
       # passing 'nil' to firstOrd/lastOrd here as type checking rules should
-      # not depent on the target integer size configurations!
+      # not depend on the target integer size configurations!
       # integer literal in the proper range; we want ``i16 + 4`` to stay an
       # ``int16`` operation so we declare the ``4`` pseudo-equal to int16
       result = isFromIntLit
@@ -396,7 +397,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
        f.kind in {tyUInt8..tyUInt32} and a[0].kind in {tyUInt8..tyInt32}) and
       a.n[0].intVal >= firstOrd(nil, f) and a.n[1].intVal <= lastOrd(nil, f):
       # passing 'nil' to firstOrd/lastOrd here as type checking rules should
-      # not depent on the target integer size configurations!
+      # not depend on the target integer size configurations!
       result = isConvertible
     else: result = isNone
 
@@ -408,13 +409,13 @@ proc isConvertibleToRange(f, a: PType): bool =
     of tyInt16: result = isIntLit(a) or a.kind in {tyInt8, tyInt16}
     of tyInt32: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32}
     # This is wrong, but seems like there's a lot of code that relies on it :(
-    of tyInt: result = true
+    of tyInt, tyUInt, tyUInt64: result = true
     of tyInt64: result = isIntLit(a) or a.kind in {tyInt8, tyInt16, tyInt32, tyInt, tyInt64}
     of tyUInt8: result = isIntLit(a) or a.kind in {tyUInt8}
     of tyUInt16: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16}
     of tyUInt32: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32}
-    of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
-    of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64}
+    #of tyUInt: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt}
+    #of tyUInt64: result = isIntLit(a) or a.kind in {tyUInt8, tyUInt16, tyUInt32, tyUInt, tyUInt64}
     else: result = false
   elif f.kind in {tyFloat..tyFloat128}:
     # `isIntLit` is correct and should be used above as well, see PR:
@@ -2362,7 +2363,7 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
         localError(c.config, n.sons[a].info, "named parameter has to be an identifier")
         noMatch()
         return
-      formal = getSymFromList(m.callee.n, n.sons[a].sons[0].ident, 1)
+      formal = getNamedParamFromList(m.callee.n, n.sons[a].sons[0].ident)
       if formal == nil:
         # no error message!
         noMatch()
diff --git a/compiler/types.nim b/compiler/types.nim
index 7dfc25026..a05625327 100644
--- a/compiler/types.nim
+++ b/compiler/types.nim
@@ -1309,7 +1309,7 @@ proc typeAllowedAux(marker: var IntSet, typ: PType, kind: TSymKind,
      tyNone, tyForward, tyFromExpr:
     result = t
   of tyNil:
-    if kind != skConst and kind != skParam and kind != skResult: result = t
+    if kind != skConst and kind != skParam: result = t
   of tyString, tyBool, tyChar, tyEnum, tyInt..tyUInt64, tyCString, tyPointer:
     result = nil
   of tyOrdinal:
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 0b76828b3..8863b2dc9 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1288,7 +1288,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
     if dest < 0: dest = c.getTemp(n.typ)
     c.gABC(n, opcCallSite, dest)
   of mNGenSym: genBinaryABC(c, n, dest, opcGenSym)
-  of mMinI, mMaxI, mAbsF64, mMinF64, mMaxF64, mAbsI, mDotDot:
+  of mMinI, mMaxI, mAbsI, mDotDot:
     c.genCall(n, dest)
   of mExpandToAst:
     if n.len != 2:
diff --git a/lib/pure/nimprof.nim b/lib/pure/nimprof.nim
index 27b7d3eca..550664f4f 100644
--- a/lib/pure/nimprof.nim
+++ b/lib/pure/nimprof.nim
@@ -14,6 +14,9 @@
 when not defined(profiler) and not defined(memProfiler):
   {.error: "Profiling support is turned off! Enable profiling by passing `--profiler:on --stackTrace:on` to the compiler (see the Nim Compiler User Guide for more options).".}
 
+when defined(nimHasUsed):
+  {.used.}
+
 # We don't want to profile the profiling code ...
 {.push profiler: off.}
 
diff --git a/lib/system.nim b/lib/system.nim
index 9605049fc..d3fd9ddc8 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -2880,17 +2880,21 @@ proc max*[T](x: openArray[T]): T =
   for i in 1..high(x):
     if result < x[i]: result = x[i]
 
-proc abs*(x: float): float {.magic: "AbsF64", noSideEffect.} =
+proc abs*(x: float64): float64 {.noSideEffect, inline.} =
   if x < 0.0: -x else: x
-proc min*(x, y: float): float {.magic: "MinF64", noSideEffect.} =
-  if x <= y: x else: y
-proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.} =
-  if y <= x: x else: y
-
-proc min*[T](x, y: T): T {.inline.}=
+proc abs*(x: float32): float32 {.noSideEffect, inline.} =
+  if x < 0.0: -x else: x
+proc min*(x, y: float32): float32 {.noSideEffect, inline.} =
+  if x <= y or y != y: x else: y
+proc min*(x, y: float64): float64 {.noSideEffect, inline.} =
+  if x <= y or y != y: x else: y
+proc max*(x, y: float32): float32 {.noSideEffect, inline.} =
+  if y <= x or y != y: x else: y
+proc max*(x, y: float64): float64 {.noSideEffect, inline.} =
+  if y <= x or y != y: x else: y
+proc min*[T: not SomeFloat](x, y: T): T {.inline.} =
   if x <= y: x else: y
-
-proc max*[T](x, y: T): T {.inline.}=
+proc max*[T: not SomeFloat](x, y: T): T {.inline.} =
   if y <= x: x else: y
 {.pop.}
 
diff --git a/tests/ccgbugs/tnil_type.nim b/tests/ccgbugs/tnil_type.nim
index 12310dae9..9921b24a3 100644
--- a/tests/ccgbugs/tnil_type.nim
+++ b/tests/ccgbugs/tnil_type.nim
@@ -13,6 +13,3 @@ f3(typeof(nil))
 
 proc f4[T](_: T) = discard
 f4(nil)
-
-proc f5(): typeof(nil) = nil
-discard f5()
diff --git a/tests/destructor/tnewruntime_misc.nim b/tests/destructor/tnewruntime_misc.nim
index d6c03b9b0..8abf0d30b 100644
--- a/tests/destructor/tnewruntime_misc.nim
+++ b/tests/destructor/tnewruntime_misc.nim
@@ -85,3 +85,16 @@ testWrongAt()
 
 let (a, d) = allocCounters()
 discard cprintf("%ld  new: %ld\n", a - unpairedEnvAllocs() - d, allocs)
+
+#-------------------------------------------------
+type
+  Table[A, B] = object
+    x: seq[(A, B)]
+
+
+proc toTable[A,B](p: sink openArray[(A, B)]): Table[A, B] = 
+  for zz in mitems(p):
+    result.x.add move(zz)
+
+
+let table = {"a": new(int)}.toTable()
diff --git a/tests/range/trange.nim b/tests/range/trange.nim
index aac967777..c864387f6 100644
--- a/tests/range/trange.nim
+++ b/tests/range/trange.nim
@@ -136,3 +136,9 @@ block:
     const x11: range[0'f..1'f] = 2'f
   reject:
     const x12: range[0'f..1'f] = 2
+
+# ensure unsigned array indexing is remains lenient:
+var a: array[4'u, string]
+
+for i in 0..<a.len:
+  a[i] = "foo"
diff --git a/tests/system/tsystem_misc.nim b/tests/system/tsystem_misc.nim
index 9dcd9ac9f..38be01a13 100644
--- a/tests/system/tsystem_misc.nim
+++ b/tests/system/tsystem_misc.nim
@@ -160,7 +160,6 @@ block: # `$`*[T: tuple|object](x: T)
   doAssert $Foo(x:2) == "(x: 2, x2: 0.0)"
   doAssert $() == "()"
 
-
 # this is a call indirection to prevent `toInt` to be resolved at compile time.
 proc testToInt(arg: float64, a: int, b: BiggestInt) =
   doAssert toInt(arg) == a
@@ -174,3 +173,14 @@ testToInt(13.37, 13, 13)    # should round towards 0
 testToInt(-13.37, -13, -13) # should round towards 0
 testToInt(7.8, 8, 8)     # should round away from 0
 testToInt(-7.8, -8, -8)  # should round away from 0
+
+# test min/max for correct NaN handling
+
+proc testMinMax(a,b: float32) =
+  doAssert max(float32(a),float32(b)) == 0'f32
+  doAssert min(float32(a),float32(b)) == 0'f32
+  doAssert max(float64(a),float64(b)) == 0'f64
+  doAssert min(float64(a),float64(b)) == 0'f64
+
+testMinMax(0.0, NaN)
+testMinMax(NaN, 0.0)
diff --git a/tests/template/tparams_gensymed.nim b/tests/template/tparams_gensymed.nim
index f7a02efa0..fe5608add 100644
--- a/tests/template/tparams_gensymed.nim
+++ b/tests/template/tparams_gensymed.nim
@@ -9,6 +9,11 @@ output: '''
 2
 3
 wth
+3
+2
+1
+0
+(total: 6)
 '''
 """
 # bug #1915
@@ -145,3 +150,17 @@ macro m(): untyped =
 
 let meh = m()
 meh("wth")
+
+
+macro foo(body: untyped): untyped =
+  result = body
+
+template baz(): untyped =
+  foo:
+    proc bar2(b: int): int =
+      echo b
+      if b > 0: b + bar2(b = b - 1)
+      else: 0
+  echo (total: bar2(3))
+
+baz()