diff options
-rwxr-xr-x | compiler/nimsets.nim | 4 | ||||
-rwxr-xr-x | compiler/semtypes.nim | 15 | ||||
-rw-r--r-- | tests/reject/tcaseoverlaprange.nim | 15 | ||||
-rwxr-xr-x | todo.txt | 1 |
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 ============= |