summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala6
-rw-r--r--test/files/run/t9516.scala52
3 files changed, 60 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index 22587c68f7..5d152ef0e8 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -117,15 +117,16 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
// binary operation
case rarg :: Nil =>
- resKind = tpeTK(larg).maxType(tpeTK(rarg))
- if (scalaPrimitives.isShiftOp(code) || scalaPrimitives.isBitwiseOp(code)) {
+ val isShiftOp = scalaPrimitives.isShiftOp(code)
+ resKind = tpeTK(larg).maxType(if (isShiftOp) INT else tpeTK(rarg))
+
+ if (isShiftOp || scalaPrimitives.isBitwiseOp(code)) {
assert(resKind.isIntegralType || (resKind == BOOL),
s"$resKind incompatible with arithmetic modulo operation.")
}
genLoad(larg, resKind)
- genLoad(rarg, // check .NET size of shift arguments!
- if (scalaPrimitives.isShiftOp(code)) INT else resKind)
+ genLoad(rarg, if (isShiftOp) INT else resKind)
(code: @switch) match {
case ADD => bc add resKind
diff --git a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala
index 2f4771e9d4..828a79ac4f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala
@@ -102,13 +102,13 @@ abstract class ConstantFolder {
case nme.XOR => Constant(x.longValue ^ y.longValue)
case nme.AND => Constant(x.longValue & y.longValue)
case nme.LSL if x.tag <= IntTag
- => Constant(x.intValue << y.longValue)
+ => Constant(x.intValue << y.longValue.toInt) // TODO: remove .toInt once starr includes the fix for SI-9516 (2.12.0-M5)
case nme.LSL => Constant(x.longValue << y.longValue)
case nme.LSR if x.tag <= IntTag
- => Constant(x.intValue >>> y.longValue)
+ => Constant(x.intValue >>> y.longValue.toInt) // TODO: remove .toInt once starr includes the fix for SI-9516 (2.12.0-M5)
case nme.LSR => Constant(x.longValue >>> y.longValue)
case nme.ASR if x.tag <= IntTag
- => Constant(x.intValue >> y.longValue)
+ => Constant(x.intValue >> y.longValue.toInt) // TODO: remove .toInt once starr includes the fix for SI-9516 (2.12.0-M5)
case nme.ASR => Constant(x.longValue >> y.longValue)
case nme.EQ => Constant(x.longValue == y.longValue)
case nme.NE => Constant(x.longValue != y.longValue)
diff --git a/test/files/run/t9516.scala b/test/files/run/t9516.scala
new file mode 100644
index 0000000000..b3068dd1ff
--- /dev/null
+++ b/test/files/run/t9516.scala
@@ -0,0 +1,52 @@
+object Test {
+ def main(args: Array[String]): Unit = {
+ intShiftLeftLongConstantFolded()
+ intShiftLeftLongAtRuntime()
+ intShiftLogicalRightLongConstantFolded()
+ intShiftLogicalRightLongAtRuntime()
+ intShiftArithmeticRightLongConstantFolded()
+ intShiftArithmeticRightLongAtRuntime()
+ }
+
+ def intShiftLeftLongConstantFolded(): Unit = {
+ assert(0x01030507 << 36L == 271601776)
+ val r = 0x01030507 << 36L
+ assert(r == 271601776)
+ }
+
+ def intShiftLeftLongAtRuntime(): Unit = {
+ var x: Int = 0x01030507
+ var y: Long = 36L
+ assert(x << y == 271601776)
+ val r = x << y
+ assert(r == 271601776)
+ }
+
+ def intShiftLogicalRightLongConstantFolded(): Unit = {
+ assert(0x90503010 >>> 36L == 151323393)
+ val r = 0x90503010 >>> 36L
+ assert(r == 151323393)
+ }
+
+ def intShiftLogicalRightLongAtRuntime(): Unit = {
+ var x: Int = 0x90503010
+ var y: Long = 36L
+ assert(x >>> y == 151323393)
+ val r = x >>> y
+ assert(r == 151323393)
+ }
+
+ def intShiftArithmeticRightLongConstantFolded(): Unit = {
+ assert(0x90503010 >> 36L == -117112063)
+ val r = 0x90503010 >> 36L
+ assert(r == -117112063)
+ }
+
+ def intShiftArithmeticRightLongAtRuntime(): Unit = {
+ var x: Int = 0x90503010
+ var y: Long = 36L
+ assert(x >> y == -117112063)
+ val r = x >> y
+ assert(r == -117112063)
+ }
+}