Avoid signed shifts and bit operations for sets.

Set operations used "1<<n" style shifts, which led to undefined
behavior if the signed shift overflowed. Similarly, the right-hand
side of the operator sometimes used a mix of signed and unsigned
integers that were combined with "&". This patch attempts to provide
a consistent implementation that uses unsigned integers everywhere.
This commit is contained in:
Reimer Behrends
2015-11-11 14:19:09 +01:00
parent f9ad735e55
commit 67e62302b4

View File

@@ -1415,11 +1415,11 @@ proc binaryExprIn(p: BProc, e: PNode, a, b, d: var TLoc, frmt: string) =
proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) =
case int(getSize(skipTypes(e.sons[1].typ, abstractVar)))
of 1: binaryExprIn(p, e, a, b, d, "(($1 &(1<<(($2)&7)))!=0)")
of 2: binaryExprIn(p, e, a, b, d, "(($1 &(1<<(($2)&15)))!=0)")
of 4: binaryExprIn(p, e, a, b, d, "(($1 &(1<<(($2)&31)))!=0)")
of 8: binaryExprIn(p, e, a, b, d, "(($1 &(IL64(1)<<(($2)&IL64(63))))!=0)")
else: binaryExprIn(p, e, a, b, d, "(($1[$2/8] &(1<<($2%8)))!=0)")
of 1: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&7U)))!=0)")
of 2: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&15U)))!=0)")
of 4: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&31U)))!=0)")
of 8: binaryExprIn(p, e, a, b, d, "(($1 &((NU64)1<<((NU)($2)&63U)))!=0)")
else: binaryExprIn(p, e, a, b, d, "(($1[(NU)($2)>>3] &(1U<<((NU)($2)&7U)))!=0)")
proc binaryStmtInExcl(p: BProc, e: PNode, d: var TLoc, frmt: string) =
var a, b: TLoc
@@ -1500,8 +1500,8 @@ proc genSetOp(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
else: internalError(e.info, "genSetOp()")
else:
case op
of mIncl: binaryStmtInExcl(p, e, d, "$1[$2/8] |=(1<<($2%8));$n")
of mExcl: binaryStmtInExcl(p, e, d, "$1[$2/8] &= ~(1<<($2%8));$n")
of mIncl: binaryStmtInExcl(p, e, d, "$1[(NU)($2)>>3] |=(1U<<($2&7U));$n")
of mExcl: binaryStmtInExcl(p, e, d, "$1[(NU)($2)>>3]] &= ~(1U<<($2&7U));$n")
of mCard: unaryExprChar(p, e, d, "#cardSet($1, " & $size & ')')
of mLtSet, mLeSet:
getTemp(p, getSysType(tyInt), i) # our counter
@@ -1788,11 +1788,11 @@ proc genSetConstr(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[i].sons[0], a)
initLocExpr(p, e.sons[i].sons[1], b)
lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" &
"$2[$1/8] |=(1<<($1%8));$n", [rdLoc(idx), rdLoc(d),
"$2[(NU)($1)>>3] |=(1U<<((NU)($1)&7U));$n", [rdLoc(idx), rdLoc(d),
rdSetElemLoc(a, e.typ), rdSetElemLoc(b, e.typ)])
else:
initLocExpr(p, e.sons[i], a)
lineF(p, cpsStmts, "$1[$2/8] |=(1<<($2%8));$n",
lineF(p, cpsStmts, "$1[(NU)($2)>>3] |=(1U<<((NU)($2)&7U));$n",
[rdLoc(d), rdSetElemLoc(a, e.typ)])
else:
# small set