fix right shift c codegen bug. (#5919)

* 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.
This commit is contained in:
Parashurama
2017-05-31 21:05:14 +02:00
committed by Andreas Rumpf
parent 199f061ddc
commit da52ade86e
2 changed files with 22 additions and 3 deletions

View File

@@ -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
@@ -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

18
tests/arithm/tshr.nim Normal file
View File

@@ -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()