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:
parent
f9ad735e55
commit
67e62302b4
1 changed files with 9 additions and 9 deletions
|
|
@ -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) =
|
proc genInExprAux(p: BProc, e: PNode, a, b, d: var TLoc) =
|
||||||
case int(getSize(skipTypes(e.sons[1].typ, abstractVar)))
|
case int(getSize(skipTypes(e.sons[1].typ, abstractVar)))
|
||||||
of 1: binaryExprIn(p, e, a, b, d, "(($1 &(1<<(($2)&7)))!=0)")
|
of 1: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&7U)))!=0)")
|
||||||
of 2: binaryExprIn(p, e, a, b, d, "(($1 &(1<<(($2)&15)))!=0)")
|
of 2: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&15U)))!=0)")
|
||||||
of 4: binaryExprIn(p, e, a, b, d, "(($1 &(1<<(($2)&31)))!=0)")
|
of 4: binaryExprIn(p, e, a, b, d, "(($1 &(1U<<((NU)($2)&31U)))!=0)")
|
||||||
of 8: binaryExprIn(p, e, a, b, d, "(($1 &(IL64(1)<<(($2)&IL64(63))))!=0)")
|
of 8: binaryExprIn(p, e, a, b, d, "(($1 &((NU64)1<<((NU)($2)&63U)))!=0)")
|
||||||
else: binaryExprIn(p, e, a, b, d, "(($1[$2/8] &(1<<($2%8)))!=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) =
|
proc binaryStmtInExcl(p: BProc, e: PNode, d: var TLoc, frmt: string) =
|
||||||
var a, b: TLoc
|
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: internalError(e.info, "genSetOp()")
|
||||||
else:
|
else:
|
||||||
case op
|
case op
|
||||||
of mIncl: 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[$2/8] &= ~(1<<($2%8));$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 mCard: unaryExprChar(p, e, d, "#cardSet($1, " & $size & ')')
|
||||||
of mLtSet, mLeSet:
|
of mLtSet, mLeSet:
|
||||||
getTemp(p, getSysType(tyInt), i) # our counter
|
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[0], a)
|
||||||
initLocExpr(p, e.sons[i].sons[1], b)
|
initLocExpr(p, e.sons[i].sons[1], b)
|
||||||
lineF(p, cpsStmts, "for ($1 = $3; $1 <= $4; $1++) $n" &
|
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)])
|
rdSetElemLoc(a, e.typ), rdSetElemLoc(b, e.typ)])
|
||||||
else:
|
else:
|
||||||
initLocExpr(p, e.sons[i], a)
|
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)])
|
[rdLoc(d), rdSetElemLoc(a, e.typ)])
|
||||||
else:
|
else:
|
||||||
# small set
|
# small set
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue