summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-01-27 22:58:21 +0100
committerAraq <rumpf_a@web.de>2013-01-27 22:58:21 +0100
commitd5a5c2291f7b7cccb6f15edc05efca12638a3976 (patch)
treea0414f5974e2f4f023ae47f4db0ecc15deebe7f5 /compiler
parent07585088955c1fe8fb815c40409ed9f5d66fd446 (diff)
downloadNim-d5a5c2291f7b7cccb6f15edc05efca12638a3976.tar.gz
bugfix: overlap checking for 'case'
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/nimsets.nim4
-rwxr-xr-xcompiler/semtypes.nim15
2 files changed, 10 insertions, 9 deletions
diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim
index 282188c64..14e9ae726 100755
--- a/compiler/nimsets.nim
+++ b/compiler/nimsets.nim
@@ -47,9 +47,9 @@ proc inSet(s: PNode, elem: PNode): bool =
 proc overlap(a, b: PNode): bool = 
   if a.kind == nkRange: 
     if b.kind == nkRange: 
+      # X..Y and C..D overlap iff (X <= D and C <= Y)
       result = leValue(a.sons[0], b.sons[1]) and
-          leValue(b.sons[1], a.sons[1]) or
-          leValue(a.sons[0], b.sons[0]) and leValue(b.sons[0], a.sons[1])
+               leValue(b.sons[0], a.sons[1])
     else:
       result = leValue(a.sons[0], b) and leValue(b, a.sons[1])
   else:
diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim
index 3ad275601..bda0047ca 100755
--- a/compiler/semtypes.nim
+++ b/compiler/semtypes.nim
@@ -311,11 +311,12 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
   else:
     result = semIdentVis(c, kind, n, allowed)
   
-proc checkForOverlap(c: PContext, t, ex: PNode, branchIndex: int) = 
-  let ex = ex.skipConv
-  for i in countup(1, branchIndex - 1): 
+proc checkForOverlap(c: PContext, t: PNode, currentEx, branchIndex: int) =
+  let ex = t[branchIndex][currentEx].skipConv
+  for i in countup(1, branchIndex):
     for j in countup(0, sonsLen(t.sons[i]) - 2): 
-      if overlap(t.sons[i].sons[j].skipConv, ex): 
+      if i == branchIndex and j == currentEx: break
+      if overlap(t.sons[i].sons[j].skipConv, ex):
         LocalError(ex.info, errDuplicateCaseLabel)
   
 proc semBranchRange(c: PContext, t, a, b: PNode, covered: var biggestInt): PNode =
@@ -373,8 +374,8 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int,
           # caution! last son of branch must be the actions to execute:
           var L = branch.len
           swap(branch.sons[L-2], branch.sons[L-1])
-    checkForOverlap(c, t, branch.sons[i], branchIndex)
-     
+    checkForOverlap(c, t, i, branchIndex)
+    
 proc semRecordNodeAux(c: PContext, n: PNode, check: var TIntSet, pos: var int, 
                       father: PNode, rectype: PSym)
 proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int, 
@@ -397,6 +398,7 @@ proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int,
   var chckCovered = true
   for i in countup(1, sonsLen(n) - 1): 
     var b = copyTree(n.sons[i])
+    addSon(a, b)
     case n.sons[i].kind
     of nkOfBranch: 
       checkMinSonsLen(b, 2)
@@ -407,7 +409,6 @@ proc semRecordCase(c: PContext, n: PNode, check: var TIntSet, pos: var int,
     else: illFormedAst(n)
     delSon(b, sonsLen(b) - 1)
     semRecordNodeAux(c, lastSon(n.sons[i]), check, pos, b, rectype)
-    addSon(a, b)
   if chckCovered and (covered != lengthOrd(a.sons[0].typ)): 
     localError(a.info, errNotAllCasesCovered)
   addSon(father, a)