diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/ConstantFolder.scala | 6 | ||||
-rw-r--r-- | test/files/run/t9516.scala | 52 |
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) + } +} |