summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/evals.nim2
-rwxr-xr-xcompiler/msgs.nim2
-rwxr-xr-xcompiler/renderer.nim4
-rwxr-xr-xcompiler/semexprs.nim1
-rwxr-xr-xcompiler/semfold.nim5
-rwxr-xr-xcompiler/sigmatch.nim6
-rwxr-xr-xcompiler/transf.nim13
7 files changed, 23 insertions, 10 deletions
diff --git a/compiler/evals.nim b/compiler/evals.nim
index adff11567..40f1f8e01 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -829,7 +829,7 @@ proc isEmpty(n: PNode): bool =
 # Maybe the lexer should mark both the beginning and the end of expressions,
 # then this function could be removed.
 proc stringStartingLine(s: PNode): int =
-  result = s.info.line - countLines(s.strVal)
+  result = s.info.line.int - countLines(s.strVal)
 
 proc evalParseExpr(c: PEvalContext, n: PNode): PNode =
   var code = evalAux(c, n.sons[1], {})
diff --git a/compiler/msgs.nim b/compiler/msgs.nim
index efd83cfd9..03ee28df3 100755
--- a/compiler/msgs.nim
+++ b/compiler/msgs.nim
@@ -345,7 +345,7 @@ const
     warnAnalysisLoophole: "thread analysis incomplete due to unkown call '$1' [AnalysisLoophole]",
     warnDifferentHeaps: "possible inconsistency of thread local heaps [DifferentHeaps]",
     warnWriteToForeignHeap: "write to foreign heap [WriteToForeignHeap]",
-    warnImplicitNarrowing: "implicit narrowing conversion: '$1'",
+    warnImplicitNarrowing: "implicit narrowing conversion: '$1' [ImplicitNarrowing]",
     warnUser: "$1 [User]", 
     hintSuccess: "operation successful [Success]", 
     hintSuccessX: "operation successful ($# lines compiled; $# sec total; $#) [SuccessX]", 
diff --git a/compiler/renderer.nim b/compiler/renderer.nim
index 30daf7c52..58c60834f 100755
--- a/compiler/renderer.nim
+++ b/compiler/renderer.nim
@@ -1209,8 +1209,8 @@ proc initTokRender(r: var TSrcGen, n: PNode, renderFlags: TRenderFlags = {}) =
 proc getNextTok(r: var TSrcGen, kind: var TTokType, literal: var string) = 
   if r.idx < len(r.tokens): 
     kind = r.tokens[r.idx].kind
-    var length = r.tokens[r.idx].length
-    literal = substr(r.buf, r.pos + 0, r.pos + 0 + length - 1)
+    var length = r.tokens[r.idx].length.int
+    literal = substr(r.buf, r.pos, r.pos + length - 1)
     inc(r.pos, length)
     inc(r.idx)
   else: 
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 501b7ed72..22af8b4e0 100755
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1302,6 +1302,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
   of nkNilLit: 
     result.typ = getSysType(tyNil)
   of nkIntLit: 
+    # XXX this is stupid:
     if result.typ == nil: 
       let i = result.intVal
       if i >= low(int32) and i <= high(int32):
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index 66d7e98fc..ce9e03513 100755
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -190,8 +190,8 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
   of mCopyStr: result = newStrNodeT(substr(getStr(a), int(getOrdValue(b))), n)
   of mCopyStrLast: 
     result = newStrNodeT(substr(getStr(a), int(getOrdValue(b)), 
-                                         int(getOrdValue(c))), n)
-  of mFloatToStr: result = newStrNodeT($(getFloat(a)), n)
+                                           int(getOrdValue(c))), n)
+  of mFloatToStr: result = newStrNodeT($getFloat(a), n)
   of mCStrToStr, mCharToStr: result = newStrNodeT(getStrOrChar(a), n)
   of mStrToStr: result = a
   of mEnumToStr: result = newStrNodeT(ordinalValToString(a), n)
@@ -298,6 +298,7 @@ proc getAppType(n: PNode): PNode =
     result = newStrNodeT("console", n)
 
 proc foldConv*(n, a: PNode): PNode = 
+  # XXX range checks?
   case skipTypes(n.typ, abstractRange).kind
   of tyInt..tyInt64: 
     case skipTypes(a.typ, abstractRange).kind
diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim
index 7a5d959df..6819bb37f 100755
--- a/compiler/sigmatch.nim
+++ b/compiler/sigmatch.nim
@@ -162,7 +162,7 @@ proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
   else:
     var k = skipTypes(a, {tyRange}).kind
     if k == f.kind: result = isSubtype
-    elif k == tyInt:
+    elif k == tyInt and f.kind in {tyRange, tyInt8..tyUInt64}:
       # and a.n != nil and a.n.intVal >= firstOrd(f) and
       #                    a.n.intVal <= lastOrd(f):
       # integer literal in the proper range; we want ``i16 + 4`` to stay an
@@ -188,7 +188,9 @@ proc handleFloatRange(f, a: PType): TTypeRelation =
   else: 
     var k = skipTypes(a, {tyRange}).kind
     if k == f.kind: result = isSubtype
-    elif (k >= tyFloat) and (k <= tyFloat128): result = isConvertible
+    elif k == tyInt and f.kind >= tyFloat and f.kind <= tyFloat128:
+      result = isIntConv
+    elif k >= tyFloat and k <= tyFloat128: result = isConvertible
     else: result = isNone
   
 proc isObjectSubtype(a, f: PType): bool =
diff --git a/compiler/transf.nim b/compiler/transf.nim
index 19530b82a..bf6354665 100755
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -640,6 +640,14 @@ proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
   result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkBracket} and 
       cnst.len != 0
 
+proc warnNarrowingConversion(n: PNode) =
+  if n.kind == nkHiddenStdConv:
+    var dest = skipTypes(n.typ, abstractVarRange)
+    var source = skipTypes(n.sons[1].typ, abstractVarRange)
+    if source.kind == tyInt and
+       source.size > dest.size and n.sons[1].kind != nkIntLit:
+      Message(n.info, warnImplicitNarrowing, renderTree(n.sons[1]))
+
 proc transform(c: PTransf, n: PNode): PTransNode = 
   case n.kind
   of nkSym: 
@@ -725,8 +733,9 @@ proc transform(c: PTransf, n: PNode): PTransNode =
   var cnst = getConstExpr(c.module, PNode(result))
   # we inline constants if they are not complex constants:
   if cnst != nil and not dontInlineConstant(n, cnst):
-    result = PTransNode(cnst) # do not miss an optimization  
- 
+    result = PTransNode(cnst) # do not miss an optimization
+  warnNarrowingConversion(result.pnode)
+
 proc processTransf(context: PPassContext, n: PNode): PNode = 
   # Note: For interactive mode we cannot call 'passes.skipCodegen' and skip
   # this step! We have to rely that the semantic pass transforms too errornous