summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xcompiler/nimsets.nim4
-rwxr-xr-xcompiler/semtypes.nim15
-rw-r--r--tests/reject/tcaseoverlaprange.nim15
-rwxr-xr-xtodo.txt1
4 files changed, 25 insertions, 10 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)
diff --git a/tests/reject/tcaseoverlaprange.nim b/tests/reject/tcaseoverlaprange.nim
new file mode 100644
index 000000000..5f24c3ca9
--- /dev/null
+++ b/tests/reject/tcaseoverlaprange.nim
@@ -0,0 +1,15 @@
+discard """
+  line: 13
+  errormsg: "duplicate case label"
+"""
+
+type
+  TE = enum A, B, C, D
+
+var
+  e: TE
+  
+case e
+of A..D, B..C: 
+  echo "redundant"
+else: nil
diff --git a/todo.txt b/todo.txt
index 7da08f2bb..bac951e8b 100755
--- a/todo.txt
+++ b/todo.txt
@@ -4,7 +4,6 @@ version 0.9.2
 - implement constructors + full 'not nil' checking
 - ``restrict`` pragma + backend support
 - fix: 'result' is not properly cleaned for NRVO
-- fix: exhaustive checking in case statements
 
 version 0.9.4
 =============