mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-14 08:45:37 +00:00
Do not directly cast int128 to uint64 in semfold (#25396)
int128 is an array of uint32s, so while this works on little-endian CPUs, it's completely broken on big-endian. e.g. following snippet would fail: const x = 0xFFFFFFFF'u32 const y = (x shr 1) echo y # amd64: 2147483647, s390x: 0 That in turn broke float printing, resulting in miscompilation of any code that used floats. To fix this, we now call the aptly named castToUInt64 procedure which performs the same cast portably. (Thanks to barracuda156 for helping debug this.)
This commit is contained in:
@@ -201,8 +201,8 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): P
|
||||
result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl valueB), n, idgen, g)
|
||||
else: internalError(g.config, n.info, "constant folding for shl")
|
||||
of mShrI:
|
||||
var a = cast[uint64](getInt(a))
|
||||
let b = cast[uint64](getInt(b)) and cast[uint64](n.typ.size * 8 - 1)
|
||||
var a = castToUInt64(getInt(a))
|
||||
let b = castToUInt64(getInt(b)) and cast[uint64](n.typ.size * 8 - 1)
|
||||
# To support the ``-d:nimOldShiftRight`` flag, we need to mask the
|
||||
# signed integers to cut off the extended sign bit in the internal
|
||||
# representation.
|
||||
|
||||
Reference in New Issue
Block a user