diff options
author | Oscar NihlgÄrd <oscarnihlgard@gmail.com> | 2018-02-24 14:56:17 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-02-24 14:56:17 +0100 |
commit | e4515f304abf9b9ce029b634b38fce2a398a16fc (patch) | |
tree | 6d37b5c7fddaa27c4fdb1bf80b8c091dec80f383 /compiler | |
parent | ba6e11fc888c0e8171797f5af731e6ac6b16c8e6 (diff) | |
download | Nim-e4515f304abf9b9ce029b634b38fce2a398a16fc.tar.gz |
Improve semchecking for duplicate cases in case statements (#7176)
* Improve semchecking for duplicate cases in case statements * Revert to previous solution * Improve test
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/nimsets.nim | 5 | ||||
-rw-r--r-- | compiler/semtypes.nim | 15 |
2 files changed, 16 insertions, 4 deletions
diff --git a/compiler/nimsets.nim b/compiler/nimsets.nim index 94507adf0..bda753e85 100644 --- a/compiler/nimsets.nim +++ b/compiler/nimsets.nim @@ -151,6 +151,11 @@ proc complement*(a: PNode): PNode = for i in countup(0, high(x)): x[i] = not x[i] result = toTreeSet(x, a.typ, a.info) +proc deduplicate*(a: PNode): PNode = + var x: TBitSet + toBitSet(a, x) + result = toTreeSet(x, a.typ, a.info) + proc cardSet(s: PNode): BiggestInt = # here we can do better than converting it into a compact set # we just count the elements directly diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index df274c7db..50c2e287e 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -497,8 +497,8 @@ proc semCaseBranchSetElem(c: PContext, t, b: PNode, proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, covered: var BiggestInt) = - - for i in countup(0, sonsLen(branch) - 2): + let lastIndex = sonsLen(branch) - 2 + for i in 0..lastIndex: var b = branch.sons[i] if b.kind == nkRange: branch.sons[i] = b @@ -516,14 +516,21 @@ proc semCaseBranch(c: PContext, t, branch: PNode, branchIndex: int, branch.sons[i] = skipConv(fitNode(c, t.sons[0].typ, r, r.info)) inc(covered) else: + if r.kind == nkCurly: + r = r.deduplicate + # first element is special and will overwrite: branch.sons[i]: branch.sons[i] = semCaseBranchSetElem(c, t, r[0], covered) + # other elements have to be added to ``branch`` for j in 1 ..< r.len: branch.add(semCaseBranchSetElem(c, t, r[j], covered)) # caution! last son of branch must be the actions to execute: - var L = branch.len - swap(branch.sons[L-2], branch.sons[L-1]) + swap(branch.sons[^2], branch.sons[^1]) + checkForOverlap(c, t, i, branchIndex) + + # Elements added above needs to be checked for overlaps. + for i in lastIndex.succ..(sonsLen(branch) - 2): checkForOverlap(c, t, i, branchIndex) proc semRecordNodeAux(c: PContext, n: PNode, check: var IntSet, pos: var int, |