summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorArne Döring <arne.doering@gmx.net>2019-06-12 09:26:30 +0200
committerAndreas Rumpf <rumpf_a@web.de>2019-06-12 09:26:30 +0200
commite4d0f4fee0d154c6af90b160d615be17034ffcdc (patch)
tree11c607a38a2d311d4c2f9582bcfbcd6b060aae0c
parentc07973e313cb701a076bffb890c0777a555ffa16 (diff)
downloadNim-e4d0f4fee0d154c6af90b160d615be17034ffcdc.tar.gz
fix regression in semfold for old right shift (#11477)
-rw-r--r--compiler/semfold.nim17
1 files changed, 16 insertions, 1 deletions
diff --git a/compiler/semfold.nim b/compiler/semfold.nim
index cb88ee6dd..3957baef4 100644
--- a/compiler/semfold.nim
+++ b/compiler/semfold.nim
@@ -248,8 +248,23 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
       result = doAndFit(newIntNodeT(`shl`(getInt(a), getInt(b)), n, g))
     else: internalError(g.config, n.info, "constant folding for shl")
   of mShrI:
-    let a = cast[uint64](getInt(a))
+    var a = cast[uint64](getInt(a))
     let b = cast[uint64](getInt(b))
+    # To support the ``-d:nimOldShiftRight`` flag, we need to mask the
+    # signed integers to cut off the extended sign bit in the internal
+    # representation.
+    if 0'u64 < b: # do not cut off the sign extension, when there is
+              # no bit shifting happening.
+      case skipTypes(n.typ, abstractRange).kind
+      of tyInt8: a = a and 0xff'u64
+      of tyInt16: a = a and 0xffff'u64
+      of tyInt32: a = a and 0xffffffff'u64
+      of tyInt:
+        if g.config.target.intSize == 4:
+          a = a and 0xffffffff'u64
+      else:
+        # unsigned and 64 bit integers don't need masking
+        discard
     let c = cast[BiggestInt](a shr b)
     result = newIntNodeT(c, n, g)
   of mAshrI: