summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2015-03-21 15:18:32 +0100
committerAraq <rumpf_a@web.de>2015-03-21 20:38:27 +0100
commit5641be51c1eefc7887361c2ad986ca20d7135e7b (patch)
tree6c98433e48acca2bfdb21f1a5b2fe86f69358dd1
parent508e8bd686050f09b7b6ca720e5b1b037a6bac62 (diff)
downloadNim-5641be51c1eefc7887361c2ad986ca20d7135e7b.tar.gz
codegen doesn't produce line tracing commands anymore; fixes #1344
-rw-r--r--compiler/ast.nim10
-rw-r--r--compiler/ccgexprs.nim97
-rw-r--r--compiler/ccgstmts.nim3
-rw-r--r--compiler/cgen.nim19
-rw-r--r--compiler/cgendata.nim13
-rw-r--r--compiler/jsgen.nim12
-rw-r--r--compiler/platform.nim284
-rw-r--r--lib/system.nim12
-rw-r--r--tests/misc/trangechecks.nim43
9 files changed, 277 insertions, 216 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 660f3e45e..a779f6636 100644
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -532,12 +532,14 @@ type
     mLow, mHigh, mSizeOf, mTypeTrait, mIs, mOf,
     mEcho, mShallowCopy, mSlurp, mStaticExec,
     mParseExprToAst, mParseStmtToAst, mExpandToAst, mQuoteAst,
-    mUnaryLt, mSucc,
-    mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
+    mUnaryLt, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mLengthOpenArray,
     mLengthStr, mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref,
-    mGCunref, mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
-    mDivI64, mModI64,
+    mGCunref,
+
+    mAddI, mSubI, mMulI, mDivI, mModI, mAddI64, mSubI64, mMulI64,
+    mDivI64, mModI64, mSucc, mPred,
     mAddF64, mSubF64, mMulF64, mDivF64,
+
     mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI,
     mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, mMaxI64,
     mMinF64, mMaxF64, mAddU, mSubU, mMulU,
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 2b26b33e7..1ebf85771 100644
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -485,37 +485,48 @@ proc unaryExprChar(p: BProc, e: PNode, d: var TLoc, frmt: string) =
   initLocExpr(p, e.sons[1], a)
   putIntoDest(p, d, e.typ, ropecg(p.module, frmt, [rdCharLoc(a)]))
 
+proc binaryArithOverflowRaw(p: BProc, t: PType, a, b: TLoc;
+                            frmt: string): PRope =
+  var size = getSize(t)
+  let storage = if size < platform.intSize: toRope("NI")
+                else: getTypeDesc(p.module, t)
+  result = getTempName()
+  linefmt(p, cpsLocals, "$1 $2;$n", storage, result)
+  lineCg(p, cpsStmts, frmt, result, rdLoc(a), rdLoc(b))
+  if size < platform.intSize or t.kind in {tyRange, tyEnum}:
+    linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
+            result, intLiteral(firstOrd(t)), intLiteral(lastOrd(t)))
+
 proc binaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   const
-    prc: array[mAddI..mModI64, string] = ["addInt", "subInt", "mulInt",
-      "divInt", "modInt", "addInt64", "subInt64", "mulInt64", "divInt64",
-      "modInt64"]
-    opr: array[mAddI..mModI64, string] = ["+", "-", "*", "/", "%", "+", "-",
-      "*", "/", "%"]
+    prc: array[mAddI..mPred, string] = [
+      "$# = #addInt($#, $#);$n", "$# = #subInt($#, $#);$n",
+      "$# = #mulInt($#, $#);$n", "$# = #divInt($#, $#);$n",
+      "$# = #modInt($#, $#);$n",
+      "$# = #addInt64($#, $#);$n", "$# = #subInt64($#, $#);$n",
+      "$# = #mulInt64($#, $#);$n", "$# = #divInt64($#, $#);$n",
+      "$# = #modInt64($#, $#);$n",
+      "$# = #addInt($#, $#);$n", "$# = #subInt($#, $#);$n"]
+    opr: array[mAddI..mPred, string] = [
+      "($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)",
+      "($#)($# / $#)", "($#)($# % $#)",
+      "($#)($# + $#)", "($#)($# - $#)", "($#)($# * $#)",
+      "($#)($# / $#)", "($#)($# % $#)",
+      "($#)($# + $#)", "($#)($# - $#)"]
   var a, b: TLoc
   assert(e.sons[1].typ != nil)
   assert(e.sons[2].typ != nil)
   initLocExpr(p, e.sons[1], a)
   initLocExpr(p, e.sons[2], b)
-  var t = skipTypes(e.typ, abstractRange)
+  # skipping 'range' is correct here as we'll generate a proper range check
+  # later via 'chckRange'
+  let t = e.typ.skipTypes(abstractRange)
   if optOverflowCheck notin p.options:
-    putIntoDest(p, d, e.typ, ropef("(NI$4)($2 $1 $3)", [toRope(opr[m]),
-        rdLoc(a), rdLoc(b), toRope(getSize(t) * 8)]))
+    let res = ropef(opr[m], [getTypeDesc(p.module, t), rdLoc(a), rdLoc(b)])
+    putIntoDest(p, d, e.typ, res)
   else:
-    var storage: PRope
-    var size = getSize(t)
-    if size < platform.intSize:
-      storage = toRope("NI")
-    else:
-      storage = getTypeDesc(p.module, t)
-    var tmp = getTempName()
-    linefmt(p, cpsLocals, "$1 $2;$n", storage, tmp)
-    lineCg(p, cpsStmts, "$1 = #$2($3, $4);$n",
-                         tmp, toRope(prc[m]), rdLoc(a), rdLoc(b))
-    if size < platform.intSize or t.kind in {tyRange, tyEnum, tySet}:
-      linefmt(p, cpsStmts, "if ($1 < $2 || $1 > $3) #raiseOverflow();$n",
-              tmp, intLiteral(firstOrd(t)), intLiteral(lastOrd(t)))
-    putIntoDest(p, d, e.typ, ropef("(NI$1)($2)", [toRope(getSize(t)*8), tmp]))
+    let res = binaryArithOverflowRaw(p, t, a, b, prc[m])
+    putIntoDest(p, d, e.typ, ropef("($#)($#)", [getTypeDesc(p.module, t), res]))
 
 proc unaryArithOverflow(p: BProc, e: PNode, d: var TLoc, m: TMagic) =
   const
@@ -1648,35 +1659,35 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
   of mAddF64..mDivF64: binaryFloatArith(p, e, d, op)
   of mShrI..mXor: binaryArith(p, e, d, op)
   of mEqProc: genEqProc(p, e, d)
-  of mAddI..mModI64: binaryArithOverflow(p, e, d, op)
+  of mAddI..mPred: binaryArithOverflow(p, e, d, op)
   of mRepr: genRepr(p, e, d)
   of mGetTypeInfo: genGetTypeInfo(p, e, d)
   of mSwap: genSwap(p, e, d)
   of mUnaryLt:
     if optOverflowCheck notin p.options: unaryExpr(p, e, d, "($1 - 1)")
     else: unaryExpr(p, e, d, "#subInt($1, 1)")
-  of mPred:
-    # XXX: range checking?
-    if optOverflowCheck notin p.options: binaryExpr(p, e, d, "($1 - $2)")
-    else: binaryExpr(p, e, d, "#subInt($1, $2)")
-  of mSucc:
-    # XXX: range checking?
-    if optOverflowCheck notin p.options: binaryExpr(p, e, d, "($1 + $2)")
-    else: binaryExpr(p, e, d, "#addInt($1, $2)")
-  of mInc:
-    if optOverflowCheck notin p.options:
-      binaryStmt(p, e, d, "$1 += $2;$n")
-    elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64:
-      binaryStmt(p, e, d, "$1 = #addInt64($1, $2);$n")
-    else:
-      binaryStmt(p, e, d, "$1 = #addInt($1, $2);$n")
-  of ast.mDec:
+  of mInc, mDec:
+    const opr: array [mInc..mDec, string] = ["$1 += $2;$n", "$1 -= $2;$n"]
+    const fun64: array [mInc..mDec, string] = ["$# = #addInt64($#, $#);$n",
+                                               "$# = #subInt64($#, $#);$n"]
+    const fun: array [mInc..mDec, string] = ["$# = #addInt($#, $#);$n",
+                                             "$# = #subInt($#, $#);$n"]
     if optOverflowCheck notin p.options:
-      binaryStmt(p, e, d, "$1 -= $2;$n")
-    elif skipTypes(e.sons[1].typ, abstractVar).kind == tyInt64:
-      binaryStmt(p, e, d, "$1 = #subInt64($1, $2);$n")
+      binaryStmt(p, e, d, opr[op])
     else:
-      binaryStmt(p, e, d, "$1 = #subInt($1, $2);$n")
+      var a, b: TLoc
+      assert(e.sons[1].typ != nil)
+      assert(e.sons[2].typ != nil)
+      initLocExpr(p, e.sons[1], a)
+      initLocExpr(p, e.sons[2], b)
+
+      let underlying = skipTypes(e.sons[1].typ, {tyGenericInst, tyVar, tyRange})
+      let ranged = skipTypes(e.sons[1].typ, {tyGenericInst, tyVar})
+      let res = binaryArithOverflowRaw(p, ranged, a, b,
+        if underlying.kind == tyInt64: fun64[op] else: fun[op])
+      putIntoDest(p, a, ranged, ropef("($#)($#)", [
+        getTypeDesc(p.module, ranged), res]))
+
   of mConStrStr: genStrConcat(p, e, d)
   of mAppendStrCh:
     binaryStmt(p, e, d, "$1 = #addChar($1, $2);$n")
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 441ceb22a..0cf452985 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -978,12 +978,13 @@ proc genAsmStmt(p: BProc, t: PNode) =
     lineF(p, cpsStmts, CC[cCompiler].asmStmtFrmt, [s])
 
 proc genEmit(p: BProc, t: PNode) =
-  genLineDir(p, t)
   var s = genAsmOrEmitStmt(p, t.sons[1])
   if p.prc == nil:
     # top level emit pragma?
+    genCLineDir(p.module.s[cfsProcHeaders], t.info)
     app(p.module.s[cfsProcHeaders], s)
   else:
+    genLineDir(p, t)
     line(p, cpsStmts, s)
 
 var
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 0b0526b65..01db97e73 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -13,7 +13,7 @@ import
   ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
   options, intsets,
   nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
-  times, ropes, math, passes, rodread, wordrecg, treetab, cgmeth, condsyms,
+  ropes, math, passes, rodread, wordrecg, treetab, cgmeth, condsyms,
   rodutils, renderer, idgen, cgendata, ccgmerge, semfold, aliases, lowerings,
   semparallel
 
@@ -183,6 +183,13 @@ proc genCLineDir(r: var PRope, filename: string, line: int) =
 proc genCLineDir(r: var PRope, info: TLineInfo) =
   genCLineDir(r, info.toFullPath, info.safeLineNm)
 
+proc freshLineInfo(p: BProc; info: TLineInfo): bool =
+  if p.lastLineInfo.line != info.line or
+     p.lastLineInfo.fileIndex != info.fileIndex:
+    p.lastLineInfo.line = info.line
+    p.lastLineInfo.fileIndex = info.fileIndex
+    result = true
+
 proc genLineDir(p: BProc, t: PNode) =
   var line = t.info.safeLineNm
   if optEmbedOrigSrc in gGlobalOptions:
@@ -190,13 +197,15 @@ proc genLineDir(p: BProc, t: PNode) =
   genCLineDir(p.s(cpsStmts), t.info.toFullPath, line)
   if ({optStackTrace, optEndb} * p.options == {optStackTrace, optEndb}) and
       (p.prc == nil or sfPure notin p.prc.flags):
-    linefmt(p, cpsStmts, "#endb($1, $2);$n",
-            line.toRope, makeCString(toFilename(t.info)))
+    if freshLineInfo(p, t.info):
+      linefmt(p, cpsStmts, "#endb($1, $2);$n",
+              line.toRope, makeCString(toFilename(t.info)))
   elif ({optLineTrace, optStackTrace} * p.options ==
       {optLineTrace, optStackTrace}) and
       (p.prc == nil or sfPure notin p.prc.flags) and t.info.fileIndex >= 0:
-    linefmt(p, cpsStmts, "nimln($1, $2);$n",
-            line.toRope, t.info.quotedFilename)
+    if freshLineInfo(p, t.info):
+      linefmt(p, cpsStmts, "nimln($1, $2);$n",
+              line.toRope, t.info.quotedFilename)
 
 proc postStmtActions(p: BProc) {.inline.} =
   app(p.s(cpsStmts), p.module.injectStmt)
diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim
index bb98454a7..9e9640f59 100644
--- a/compiler/cgendata.nim
+++ b/compiler/cgendata.nim
@@ -9,9 +9,11 @@
 
 ## This module contains the data structures for the C code generation phase.
 
-import 
+import
   ast, astalgo, ropes, passes, options, intsets, lists, platform
 
+from msgs import TLineInfo
+
 type
   TLabel* = PRope             # for the C generator a label is just a rope
   TCFileSection* = enum       # the sections a generated C file consists of
@@ -51,7 +53,7 @@ type
   TCProcSections* = array[TCProcSection, PRope] # represents a generated C proc
   BModule* = ref TCGen
   BProc* = ref TCProc
-  TBlock*{.final.} = object 
+  TBlock*{.final.} = object
     id*: int                  # the ID of the label; positive means that it
     label*: PRope             # generated text for the label
                               # nil if label is not used
@@ -60,11 +62,12 @@ type
     nestedTryStmts*: int16    # how many try statements is it nested into
     nestedExceptStmts*: int16 # how many except statements is it nested into
     frameLen*: int16
-  
+
   TCProc{.final.} = object    # represents C proc that is currently generated
     prc*: PSym                # the Nim proc that this C proc belongs to
     beforeRetNeeded*: bool    # true iff 'BeforeRet' label for proc is needed
     threadVarAccessed*: bool  # true if the proc already accessed some threadvar
+    lastLineInfo*: TLineInfo  # to avoid generating excessive 'nimln' statements
     nestedTryStmts*: seq[PNode]   # in how many nested try statements we are
                                   # (the vars must be volatile then)
     inExceptBlock*: int       # are we currently inside an except block?
@@ -87,7 +90,7 @@ type
                               # (yes, C++ is weird like that)
     gcFrameId*: Natural       # for the GC stack marking
     gcFrameType*: PRope       # the struct {} we put the GC markers into
-  
+
   TTypeSeq* = seq[PType]
   TCGen = object of TPassContext # represents a C source file
     module*: PSym
@@ -140,7 +143,7 @@ proc bmod*(module: PSym): BModule =
   # obtains the BModule for a given module PSym
   result = gModules[module.position]
 
-proc newProc*(prc: PSym, module: BModule): BProc = 
+proc newProc*(prc: PSym, module: BModule): BProc =
   new(result)
   result.prc = prc
   result.module = module
diff --git a/compiler/jsgen.nim b/compiler/jsgen.nim
index 0bdaeff83..c592f3f47 100644
--- a/compiler/jsgen.nim
+++ b/compiler/jsgen.nim
@@ -262,6 +262,8 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
     ["mulInt64", "", "mulInt64($1, $2)", "($1 * $2)"], # MulI64
     ["divInt64", "", "divInt64($1, $2)", "Math.floor($1 / $2)"], # DivI64
     ["modInt64", "", "modInt64($1, $2)", "Math.floor($1 % $2)"], # ModI64
+    ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ
+    ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred
     ["", "", "($1 + $2)", "($1 + $2)"], # AddF64
     ["", "", "($1 - $2)", "($1 - $2)"], # SubF64
     ["", "", "($1 * $2)", "($1 * $2)"], # MulF64
@@ -362,6 +364,8 @@ const # magic checked op; magic unchecked op; checked op; unchecked op
     ["mulInt64", "", "mulInt64($1, $2)", "($1 * $2)"], # MulI64
     ["divInt64", "", "divInt64($1, $2)", "Math.floor($1 / $2)"], # DivI64
     ["modInt64", "", "modInt64($1, $2)", "Math.floor($1 % $2)"], # ModI64
+    ["addInt", "", "addInt($1, $2)", "($1 + $2)"], # Succ
+    ["subInt", "", "subInt($1, $2)", "($1 - $2)"], # Pred
     ["", "", "($1 + $2)", "($1 + $2)"], # AddF64
     ["", "", "($1 - $2)", "($1 - $2)"], # SubF64
     ["", "", "($1 * $2)", "($1 * $2)"], # MulF64
@@ -1323,14 +1327,6 @@ proc genMagic(p: PProc, n: PNode, r: var TCompRes) =
     # XXX: range checking?
     if not (optOverflowCheck in p.options): unaryExpr(p, n, r, "", "$1 - 1")
     else: unaryExpr(p, n, r, "subInt", "subInt($1, 1)")
-  of mPred:
-    # XXX: range checking?
-    if not (optOverflowCheck in p.options): binaryExpr(p, n, r, "", "$1 - $2")
-    else: binaryExpr(p, n, r, "subInt", "subInt($1, $2)")
-  of mSucc:
-    # XXX: range checking?
-    if not (optOverflowCheck in p.options): binaryExpr(p, n, r, "", "$1 - $2")
-    else: binaryExpr(p, n, r, "addInt", "addInt($1, $2)")
   of mAppendStrCh: binaryExpr(p, n, r, "addChar", "addChar($1, $2)")
   of mAppendStrStr:
     if skipTypes(n.sons[1].typ, abstractVarRange).kind == tyCString:
diff --git a/compiler/platform.nim b/compiler/platform.nim
index a21e73248..4dd5d8836 100644
--- a/compiler/platform.nim
+++ b/compiler/platform.nim
@@ -13,192 +13,192 @@
 # Nimrod has been tested on this platform or that the RTL has been ported.
 # Feel free to test for your excentric platform!
 
-import 
+import
   strutils
 
-type 
+type
   TSystemOS* = enum # Also add OS in initialization section and alias
                     # conditionals to condsyms (end of module).
-    osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris, 
-    osIrix, osNetbsd, osFreebsd, osOpenbsd, osAix, osPalmos, osQnx, osAmiga, 
+    osNone, osDos, osWindows, osOs2, osLinux, osMorphos, osSkyos, osSolaris,
+    osIrix, osNetbsd, osFreebsd, osOpenbsd, osAix, osPalmos, osQnx, osAmiga,
     osAtari, osNetware, osMacos, osMacosx, osHaiku, osVxworks,
     osJS, osNimrodVM, osStandalone
 
-type 
-  TInfoOSProp* = enum 
+type
+  TInfoOSProp* = enum
     ospNeedsPIC,              # OS needs PIC for libraries
     ospCaseInsensitive,       # OS filesystem is case insensitive
     ospPosix,                 # OS is posix-like
     ospLacksThreadVars        # OS lacks proper __threadvar support
   TInfoOSProps* = set[TInfoOSProp]
-  TInfoOS* = tuple[name: string, parDir: string, dllFrmt: string, 
-                   altDirSep: string, objExt: string, newLine: string, 
-                   pathSep: string, dirSep: string, scriptExt: string, 
-                   curDir: string, exeExt: string, extSep: string, 
+  TInfoOS* = tuple[name: string, parDir: string, dllFrmt: string,
+                   altDirSep: string, objExt: string, newLine: string,
+                   pathSep: string, dirSep: string, scriptExt: string,
+                   curDir: string, exeExt: string, extSep: string,
                    props: TInfoOSProps]
 
-const 
+const
   OS*: array[succ(low(TSystemOS))..high(TSystemOS), TInfoOS] = [
-     (name: "DOS", 
-      parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".obj", 
-      newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\", scriptExt: ".bat", 
-      curDir: ".", exeExt: ".exe", extSep: ".", props: {ospCaseInsensitive}), 
-     (name: "Windows", parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", 
-      objExt: ".obj", newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\", 
-      scriptExt: ".bat", curDir: ".", exeExt: ".exe", extSep: ".", 
-      props: {ospCaseInsensitive}), 
-     (name: "OS2", parDir: "..", 
-      dllFrmt: "$1.dll", altDirSep: "/", 
-      objExt: ".obj", newLine: "\x0D\x0A", 
-      pathSep: ";", dirSep: "\\", 
-      scriptExt: ".bat", curDir: ".", 
-      exeExt: ".exe", extSep: ".", 
-      props: {ospCaseInsensitive}), 
-     (name: "Linux", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix}), 
-     (name: "MorphOS", parDir: "..", 
-      dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", 
-      pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", 
-      exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix}), 
-     (name: "SkyOS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix}), 
-     (name: "Solaris", parDir: "..", 
-      dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", 
-      pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", 
-      exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix}), 
-     (name: "Irix", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix}), 
-     (name: "NetBSD", parDir: "..", 
-      dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", 
-      pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", 
-      exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix}), 
-     (name: "FreeBSD", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix}), 
-     (name: "OpenBSD", parDir: "..", 
-      dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", 
-      pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", 
-      exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix}), 
-     (name: "AIX", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix}), 
-     (name: "PalmOS", parDir: "..", 
-      dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", 
-      pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", 
-      exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC}), 
-     (name: "QNX", 
-      parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", objExt: ".o", 
-      newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".", 
-      exeExt: "", extSep: ".", props: {ospNeedsPIC, ospPosix}), 
-     (name: "Amiga", 
-      parDir: "..", dllFrmt: "$1.library", altDirSep: "/", objExt: ".o", 
-      newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".", 
-      exeExt: "", extSep: ".", props: {ospNeedsPIC}), 
-     (name: "Atari", 
-      parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".o", 
-      newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: "", curDir: ".", 
-      exeExt: ".tpp", extSep: ".", props: {ospNeedsPIC}), 
-     (name: "Netware", 
-      parDir: "..", dllFrmt: "$1.nlm", altDirSep: "/", objExt: "", 
-      newLine: "\x0D\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", 
-      curDir: ".", exeExt: ".nlm", extSep: ".", props: {ospCaseInsensitive}), 
-     (name: "MacOS", parDir: "::", dllFrmt: "$1Lib", altDirSep: ":", 
-      objExt: ".o", newLine: "\x0D", pathSep: ",", dirSep: ":", scriptExt: "", 
-      curDir: ":", exeExt: "", extSep: ".", props: {ospCaseInsensitive}), 
-     (name: "MacOSX", parDir: "..", dllFrmt: "lib$1.dylib", altDirSep: ":", 
-      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", 
-      props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}), 
-     (name: "Haiku", parDir: "..", dllFrmt: "lib$1.so", altDirSep: ":", 
-      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", 
+     (name: "DOS",
+      parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".obj",
+      newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\", scriptExt: ".bat",
+      curDir: ".", exeExt: ".exe", extSep: ".", props: {ospCaseInsensitive}),
+     (name: "Windows", parDir: "..", dllFrmt: "$1.dll", altDirSep: "/",
+      objExt: ".obj", newLine: "\x0D\x0A", pathSep: ";", dirSep: "\\",
+      scriptExt: ".bat", curDir: ".", exeExt: ".exe", extSep: ".",
+      props: {ospCaseInsensitive}),
+     (name: "OS2", parDir: "..",
+      dllFrmt: "$1.dll", altDirSep: "/",
+      objExt: ".obj", newLine: "\x0D\x0A",
+      pathSep: ";", dirSep: "\\",
+      scriptExt: ".bat", curDir: ".",
+      exeExt: ".exe", extSep: ".",
+      props: {ospCaseInsensitive}),
+     (name: "Linux", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix}),
+     (name: "MorphOS", parDir: "..",
+      dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A",
+      pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".",
+      exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix}),
+     (name: "SkyOS", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix}),
+     (name: "Solaris", parDir: "..",
+      dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A",
+      pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".",
+      exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix}),
+     (name: "Irix", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix}),
+     (name: "NetBSD", parDir: "..",
+      dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A",
+      pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".",
+      exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix}),
+     (name: "FreeBSD", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix}),
+     (name: "OpenBSD", parDir: "..",
+      dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A",
+      pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".",
+      exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix}),
+     (name: "AIX", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix}),
+     (name: "PalmOS", parDir: "..",
+      dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A",
+      pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".",
+      exeExt: "", extSep: ".",
+      props: {ospNeedsPIC}),
+     (name: "QNX",
+      parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", objExt: ".o",
+      newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".",
+      exeExt: "", extSep: ".", props: {ospNeedsPIC, ospPosix}),
+     (name: "Amiga",
+      parDir: "..", dllFrmt: "$1.library", altDirSep: "/", objExt: ".o",
+      newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh", curDir: ".",
+      exeExt: "", extSep: ".", props: {ospNeedsPIC}),
+     (name: "Atari",
+      parDir: "..", dllFrmt: "$1.dll", altDirSep: "/", objExt: ".o",
+      newLine: "\x0A", pathSep: ":", dirSep: "/", scriptExt: "", curDir: ".",
+      exeExt: ".tpp", extSep: ".", props: {ospNeedsPIC}),
+     (name: "Netware",
+      parDir: "..", dllFrmt: "$1.nlm", altDirSep: "/", objExt: "",
+      newLine: "\x0D\x0A", pathSep: ":", dirSep: "/", scriptExt: ".sh",
+      curDir: ".", exeExt: ".nlm", extSep: ".", props: {ospCaseInsensitive}),
+     (name: "MacOS", parDir: "::", dllFrmt: "$1Lib", altDirSep: ":",
+      objExt: ".o", newLine: "\x0D", pathSep: ",", dirSep: ":", scriptExt: "",
+      curDir: ":", exeExt: "", extSep: ".", props: {ospCaseInsensitive}),
+     (name: "MacOSX", parDir: "..", dllFrmt: "lib$1.dylib", altDirSep: ":",
+      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
+      props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
+     (name: "Haiku", parDir: "..", dllFrmt: "lib$1.so", altDirSep: ":",
+      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
       props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
      (name: "VxWorks", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
       objExt: ".o", newLine: "\x0A", pathSep: ";", dirSep: "\\",
       scriptExt: ".sh", curDir: ".", exeExt: ".vxe", extSep: ".",
       props: {ospNeedsPIC, ospPosix, ospLacksThreadVars}),
-     (name: "JS", parDir: "..", 
-      dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", 
-      pathSep: ":", dirSep: "/", 
-      scriptExt: ".sh", curDir: ".", 
-      exeExt: "", extSep: ".", props: {}), 
-     (name: "NimrodVM", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/", 
-      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/", 
+     (name: "JS", parDir: "..",
+      dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A",
+      pathSep: ":", dirSep: "/",
+      scriptExt: ".sh", curDir: ".",
+      exeExt: "", extSep: ".", props: {}),
+     (name: "NimrodVM", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
+      objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
       scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", props: {}),
      (name: "Standalone", parDir: "..", dllFrmt: "lib$1.so", altDirSep: "/",
       objExt: ".o", newLine: "\x0A", pathSep: ":", dirSep: "/",
-      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".", 
+      scriptExt: ".sh", curDir: ".", exeExt: "", extSep: ".",
       props: {})]
 
-type 
-  TSystemCPU* = enum # Also add CPU for in initialization section and 
+type
+  TSystemCPU* = enum # Also add CPU for in initialization section and
                      # alias conditionals to condsyms (end of module).
     cpuNone, cpuI386, cpuM68k, cpuAlpha, cpuPowerpc, cpuPowerpc64,
-    cpuSparc, cpuVm, cpuIa64, cpuAmd64, cpuMips, cpuArm, 
+    cpuSparc, cpuVm, cpuIa64, cpuAmd64, cpuMips, cpuArm,
     cpuJS, cpuNimrodVM, cpuAVR
 
-type 
-  TEndian* = enum 
+type
+  TEndian* = enum
     littleEndian, bigEndian
-  TInfoCPU* = tuple[name: string, intSize: int, endian: TEndian, 
+  TInfoCPU* = tuple[name: string, intSize: int, endian: TEndian,
                     floatSize, bit: int]
 
 const
   EndianToStr*: array[TEndian, string] = ["littleEndian", "bigEndian"]
   CPU*: array[succ(low(TSystemCPU))..high(TSystemCPU), TInfoCPU] = [
-    (name: "i386", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32), 
-    (name: "m68k", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32), 
-    (name: "alpha", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), 
+    (name: "i386", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
+    (name: "m68k", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
+    (name: "alpha", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
     (name: "powerpc", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
-    (name: "powerpc64", intSize: 64, endian: bigEndian, floatSize: 64,bit: 64), 
-    (name: "sparc", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32), 
-    (name: "vm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32), 
-    (name: "ia64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), 
-    (name: "amd64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64), 
-    (name: "mips", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32), 
-    (name: "arm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32), 
-    (name: "js", intSize: 32, endian: bigEndian,floatSize: 64,bit: 32), 
+    (name: "powerpc64", intSize: 64, endian: bigEndian, floatSize: 64,bit: 64),
+    (name: "sparc", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
+    (name: "vm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
+    (name: "ia64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
+    (name: "amd64", intSize: 64, endian: littleEndian, floatSize: 64, bit: 64),
+    (name: "mips", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
+    (name: "arm", intSize: 32, endian: littleEndian, floatSize: 64, bit: 32),
+    (name: "js", intSize: 32, endian: bigEndian,floatSize: 64,bit: 32),
     (name: "nimrodvm", intSize: 32, endian: bigEndian, floatSize: 64, bit: 32),
     (name: "avr", intSize: 16, endian: littleEndian, floatSize: 32, bit: 16)]
 
-var 
+var
   targetCPU*, hostCPU*: TSystemCPU
   targetOS*, hostOS*: TSystemOS
 
 proc nameToOS*(name: string): TSystemOS
 proc nameToCPU*(name: string): TSystemCPU
 
-var 
+var
   intSize*: int
   floatSize*: int
   ptrSize*: int
   tnl*: string                # target newline
 
-proc setTarget*(o: TSystemOS, c: TSystemCPU) = 
+proc setTarget*(o: TSystemOS, c: TSystemCPU) =
   assert(c != cpuNone)
   assert(o != osNone)
   #echo "new Target: OS: ", o, " CPU: ", c
@@ -209,15 +209,15 @@ proc setTarget*(o: TSystemOS, c: TSystemCPU) =
   ptrSize = CPU[c].bit div 8
   tnl = OS[o].newLine
 
-proc nameToOS(name: string): TSystemOS = 
-  for i in countup(succ(osNone), high(TSystemOS)): 
-    if cmpIgnoreStyle(name, OS[i].name) == 0: 
+proc nameToOS(name: string): TSystemOS =
+  for i in countup(succ(osNone), high(TSystemOS)):
+    if cmpIgnoreStyle(name, OS[i].name) == 0:
       return i
   result = osNone
 
-proc nameToCPU(name: string): TSystemCPU = 
-  for i in countup(succ(cpuNone), high(TSystemCPU)): 
-    if cmpIgnoreStyle(name, CPU[i].name) == 0: 
+proc nameToCPU(name: string): TSystemCPU =
+  for i in countup(succ(cpuNone), high(TSystemCPU)):
+    if cmpIgnoreStyle(name, CPU[i].name) == 0:
       return i
   result = cpuNone
 
diff --git a/lib/system.nim b/lib/system.nim
index 23c911a19..a57edb73a 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1557,9 +1557,9 @@ when not defined(nimrodVM) and hostOS != "standalone":
       ## process. This is only available when threads are enabled.
 
 when sizeof(int) <= 2:
-  type IntLikeForCount = int|int8|int16|char|bool|uint8
+  type IntLikeForCount = int|int8|int16|char|bool|uint8|enum
 else:
-  type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16
+  type IntLikeForCount = int|int8|int16|int32|char|bool|uint8|uint16|enum
 
 iterator countdown*[T](a, b: T, step = 1): T {.inline.} =
   ## Counts from ordinal value `a` down to `b` with the given
@@ -2900,20 +2900,16 @@ proc `[]`*[Idx, T](a: array[Idx, T], x: Slice[Idx]): seq[T] =
   ## because the array might have negative bounds.
   var L = ord(x.b) - ord(x.a) + 1
   newSeq(result, L)
-  var j = x.a
   for i in 0.. <L:
-    result[i] = a[j]
-    inc(j)
+    result[i] = a[Idx(ord(x.a) + i)]
 
 proc `[]=`*[Idx, T](a: var array[Idx, T], x: Slice[Idx], b: openArray[T]) =
   ## slice assignment for arrays. Negative indexes are **not** supported
   ## because the array might have negative bounds.
   var L = ord(x.b) - ord(x.a) + 1
   if L == b.len:
-    var j = x.a
     for i in 0 .. <L:
-      a[j] = b[i]
-      inc(j)
+      a[Idx(ord(x.a) + i)] = b[i]
   else:
     sysFatal(RangeError, "different lengths for slice assignment")
 
diff --git a/tests/misc/trangechecks.nim b/tests/misc/trangechecks.nim
new file mode 100644
index 000000000..2c6f0f66d
--- /dev/null
+++ b/tests/misc/trangechecks.nim
@@ -0,0 +1,43 @@
+discard """
+  output: '''10
+10
+1
+1
+true'''
+"""
+
+# bug #1344
+
+var expected: int
+var x: range[1..10] = 10
+
+try:
+  x += 1
+  echo x
+except OverflowError, RangeError:
+  expected += 1
+  echo x
+
+try:
+  inc x
+  echo x
+except OverflowError, RangeError:
+  expected += 1
+  echo x
+
+x = 1
+try:
+  x -= 1
+  echo x
+except OverflowError, RangeError:
+  expected += 1
+  echo x
+
+try:
+  dec x
+  echo x
+except OverflowError, RangeError:
+  expected += 1
+  echo x
+
+echo expected == 4