summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/lexer.nim18
1 files changed, 15 insertions, 3 deletions
diff --git a/compiler/lexer.nim b/compiler/lexer.nim
index 09eca3100..5c7baf7d3 100644
--- a/compiler/lexer.nim
+++ b/compiler/lexer.nim
@@ -482,9 +482,21 @@ proc getNumber(L: var TLexer): TToken =
       of tkFloat64Lit: result.fNumber = (cast[PFloat64](addr(xi)))[]
       else: internalError(getLineInfo(L), "getNumber")
 
-      # Simple bounds check
-      if result.tokType notin floatTypes and xi != result.iNumber:
-        lexMessageLitNum(L, errNumberOutOfRange, startpos)
+      # Bounds checks. Non decimal literals are allowed to overflow the range of
+      # the datatype as long as their pattern don't overflow _bitwise_, hence 
+      # below checks of signed sizes against uint*.high is deliberate:
+      # (0x80'u8 = 128, 0x80'i8 = -128, etc == OK)
+      if result.tokType notin floatTypes:
+        let outOfRange = case result.tokType:
+        of tkUInt8Lit, tkUInt16Lit, tkUInt32Lit: result.iNumber != xi
+        of tkInt8Lit: (xi > BiggestInt(uint8.high))
+        of tkInt16Lit: (xi > BiggestInt(uint16.high))
+        of tkInt32Lit: (xi > BiggestInt(uint32.high))
+        else: false
+
+        if outOfRange:
+          echo "out of range num: ", result.iNumber, " vs ", xi
+          lexMessageLitNum(L, errNumberOutOfRange, startpos)
 
     else:
       case result.tokType