mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-31 18:32:11 +00:00
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user