Skip to content

Commit

Permalink
fix right shift c codegen bug. (#5919)
Browse files Browse the repository at this point in the history
* fix right shift c codegen bug.

signed int must first be cast as unsigned before converting to larger
integer. The C compiler will auto convert operands to the largest type.
  • Loading branch information
Parashurama authored and Araq committed May 31, 2017
1 parent 199f061 commit da52ade
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
7 changes: 4 additions & 3 deletions compiler/ccgexprs.nim
Expand Up @@ -545,7 +545,7 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
"(($4)($1) * ($4)($2))", # MulF64
"(($4)($1) / ($4)($2))", # DivF64

"($4)((NU$3)($1) >> (NU$3)($2))", # ShrI
"($4)((NU$5)($1) >> (NU$3)($2))", # ShrI
"($4)((NU$3)($1) << (NU$3)($2))", # ShlI
"($4)($1 & $2)", # BitandI
"($4)($1 | $2)", # BitorI
Expand Down Expand Up @@ -585,16 +585,17 @@ proc binaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
"($1 != $2)"] # Xor
var
a, b: TLoc
s: BiggestInt
s, k: BiggestInt
assert(e.sons[1].typ != nil)
assert(e.sons[2].typ != nil)
initLocExpr(p, e.sons[1], a)
initLocExpr(p, e.sons[2], b)
# BUGFIX: cannot use result-type here, as it may be a boolean
s = max(getSize(a.t), getSize(b.t)) * 8
k = getSize(a.t) * 8
putIntoDest(p, d, e.typ,
binArithTab[op] % [rdLoc(a), rdLoc(b), rope(s),
getSimpleTypeDesc(p.module, e.typ)])
getSimpleTypeDesc(p.module, e.typ), rope(k)])

proc genEqProc(p: BProc, e: PNode, d: var TLoc) =
var a, b: TLoc
Expand Down
18 changes: 18 additions & 0 deletions tests/arithm/tshr.nim
@@ -0,0 +1,18 @@
discard """
output: ''''''
"""

proc T() =
let VI = -8
let VI64 = -8'i64
let VI32 = -8'i32
let VI16 = -8'i16
let VI8 = -8'i8
doAssert( (VI shr 1) == 9223372036854775804)
doAssert( (VI64 shr 1) == 9223372036854775804)
doAssert( (VI32 shr 1) == 2147483644)
doAssert( (VI16 shr 1) == 32764)
doAssert( (VI8 shr 1) == 124)


T()

0 comments on commit da52ade

Please sign in to comment.