summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorJasper Jenkins <jasper.vs.jenkins@gmail.com>2019-06-18 05:16:33 -0700
committerAndreas Rumpf <rumpf_a@web.de>2019-06-18 14:16:33 +0200
commit8ee0f14ab6b8decffe8673dac4d761c352d8e31d (patch)
tree952363477abebe5af2c6a3181ef1bc3f683c0967 /compiler
parentc99ce5051e7024319c2d600af8b218dfc997bde8 (diff)
downloadNim-8ee0f14ab6b8decffe8673dac4d761c352d8e31d.tar.gz
literal array indices (#11424)
Diffstat (limited to 'compiler')
-rw-r--r--compiler/semexprs.nim23
1 files changed, 19 insertions, 4 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index f53bda0ea..558b450da 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -527,16 +527,24 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
   result = newNodeI(nkBracket, n.info)
   result.typ = newTypeS(tyArray, c)
   rawAddSon(result.typ, nil)     # index type
+  var
+    firstIndex, lastIndex: BiggestInt = 0
+    indexType = getSysType(c.graph, n.info, tyInt)
+    lastValidIndex = lastOrd(c.config, indexType)
   if sonsLen(n) == 0:
     rawAddSon(result.typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
+    lastIndex = -1
   else:
     var x = n.sons[0]
-    var lastIndex: BiggestInt = 0
-    var indexType = getSysType(c.graph, n.info, tyInt)
     if x.kind == nkExprColonExpr and sonsLen(x) == 2:
       var idx = semConstExpr(c, x.sons[0])
-      lastIndex = getOrdValue(idx)
+      if not isOrdinalType(idx.typ):
+        localError(c.config, idx.info, "expected ordinal value for array " &
+                   "index, got '$1'" % renderTree(idx))
+      firstIndex = getOrdValue(idx)
+      lastIndex = firstIndex
       indexType = idx.typ
+      lastValidIndex = lastOrd(c.config, indexType)
       x = x.sons[1]
 
     let yy = semExprWithType(c, x)
@@ -544,6 +552,12 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
     addSon(result, yy)
     #var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal})
     for i in 1 ..< sonsLen(n):
+      if lastIndex == lastValidIndex:
+        let validIndex = makeRangeType(c, firstIndex, lastValidIndex, n.info,
+                                       indexType)
+        localError(c.config, n.info, "size of array exceeds range of index " &
+          "type '$1' by $2 elements" % [typeToString(validIndex), $(n.len-i)])
+
       x = n.sons[i]
       if x.kind == nkExprColonExpr and sonsLen(x) == 2:
         var idx = semConstExpr(c, x.sons[0])
@@ -561,7 +575,8 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
     addSonSkipIntLit(result.typ, typ)
     for i in 0 ..< result.len:
       result.sons[i] = fitNode(c, typ, result.sons[i], result.sons[i].info)
-  result.typ.sons[0] = makeRangeType(c, 0, sonsLen(result) - 1, n.info)
+  result.typ.sons[0] = makeRangeType(c, firstIndex, lastIndex, n.info,
+                                     indexType)
 
 proc fixAbstractType(c: PContext, n: PNode) =
   for i in 1 ..< n.len: