attempt to fix a bug concerning implicit type conversions in case statements

This commit is contained in:
Araq
2012-03-27 00:48:59 +02:00
parent 16adc837be
commit a79acb58fc
4 changed files with 26 additions and 29 deletions

View File

@@ -146,6 +146,14 @@ proc IITablePut*(t: var TIITable, key, val: int)
# implementation
proc skipConv*(n: PNode): PNode =
case n.kind
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
result = n.sons[0]
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = n.sons[1]
else: result = n
proc SameValue*(a, b: PNode): bool =
result = false
case a.kind

View File

@@ -249,43 +249,38 @@ proc semIdentWithPragma(c: PContext, kind: TSymKind, n: PNode,
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):
for j in countup(0, sonsLen(t.sons[i]) - 2):
if overlap(t.sons[i].sons[j], ex):
if overlap(t.sons[i].sons[j].skipConv, ex):
LocalError(ex.info, errDuplicateCaseLabel)
proc semBranchExpr(c: PContext, t, e: PNode): PNode =
result = semConstExpr(c, e)
proc semBranchRange(c: PContext, t, a, b: PNode, covered: var biggestInt): PNode =
checkMinSonsLen(t, 1)
result = fitNode(c, t.sons[0].typ, result)
#if cmpTypes(t.sons[0].typ, result.typ) <= isConvertible:
# typeMismatch(result, t.sons[0].typ, result.typ)
let ac = semConstExpr(c, a)
let bc = semConstExpr(c, b)
let at = fitNode(c, t.sons[0].typ, ac)
let bt = fitNode(c, t.sons[0].typ, bc)
result = newNodeI(nkRange, a.info)
result.add(at)
result.add(bt)
if emptyRange(ac, bc): GlobalError(b.info, errRangeIsEmpty)
covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1
proc SemCaseBranchRange(c: PContext, t, b: PNode,
covered: var biggestInt): PNode =
checkSonsLen(b, 3)
result = newNodeI(nkRange, b.info)
result.add(semBranchExpr(c, t, b.sons[1]))
result.add(semBranchExpr(c, t, b.sons[2]))
if emptyRange(result[0], result[1]): GlobalError(b.info, errRangeIsEmpty)
covered = covered + getOrdValue(result[1]) - getOrdValue(result[0]) + 1
result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
proc semCaseBranchSetElem(c: PContext, t, b: PNode,
covered: var biggestInt): PNode =
if isRange(b):
checkSonsLen(b, 3)
result = newNodeI(nkRange, b.info)
result.add(semBranchExpr(c, t, b.sons[1]))
result.add(semBranchExpr(c, t, b.sons[2]))
if emptyRange(result[0], result[1]): GlobalError(b.info, errRangeIsEmpty)
covered = covered + getOrdValue(result[1]) - getOrdValue(result[0]) + 1
result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)
elif b.kind == nkRange:
checkSonsLen(b, 2)
result = newNodeI(nkRange, b.info)
result.add(semBranchExpr(c, t, b.sons[0]))
result.add(semBranchExpr(c, t, b.sons[1]))
if emptyRange(result[0], result[1]): GlobalError(b.info, errRangeIsEmpty)
covered = covered + getOrdValue(result[1]) - getOrdValue(result[0]) + 1
result = semBranchRange(c, t, b.sons[0], b.sons[1], covered)
else:
result = fitNode(c, t.sons[0].typ, b)
inc(covered)

View File

@@ -267,14 +267,6 @@ proc transformLoopBody(c: PTransf, n: PNode): PTransNode =
discard c.blockSyms.pop()
else:
result = transform(c, n)
proc skipConv(n: PNode): PNode =
case n.kind
of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64:
result = n.sons[0]
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = n.sons[1]
else: result = n
proc newTupleAccess(tup: PNode, i: int): PNode =
result = newNodeIT(nkBracketExpr, tup.info, tup.typ.sons[i])

View File

@@ -1,6 +1,7 @@
version 0.9.0
=============
- fix bug #100 so that unittests work again
- ``=`` should be overloadable; requires specialization for ``=``
- fix remaining generics bugs
- fix remaining closure bugs:
@@ -99,6 +100,7 @@ version 0.9.XX
Library
-------
- provide more up to date OpenGL headers
- wrappers for mongodb; poppler; libharu
- suffix trees
- locale support; i18n module