summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
diff options
context:
space:
mode:
authorSébastien Doeraene <sjrdoeraene@gmail.com>2016-04-23 09:10:30 +0200
committerLukas Rytz <lukas.rytz@typesafe.com>2016-04-23 09:10:30 +0200
commiteb954cafa2737a6f06f8a802ceec133a88959f71 (patch)
treec4dc3d3144ac05303e4093023fe4bf8db7d083f4 /src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
parentf55dd2084eca97c576a982473ab6701f98fb79a7 (diff)
downloadscala-eb954cafa2737a6f06f8a802ceec133a88959f71.tar.gz
scala-eb954cafa2737a6f06f8a802ceec133a88959f71.tar.bz2
scala-eb954cafa2737a6f06f8a802ceec133a88959f71.zip
SI-9516 Fix the behavior of Int shift Long operations. (#5117)
In any shift operation where the lhs is an Int (or smaller) and the rhs is a Long, the result kind must be Int, and not Long. This is important because the lhs must *not* be promoted to a Long, as that causes an opcode for long shift to be emitted. This uses an rhs modulo 64, instead of int shifts which use an rhs module 32. Instead, the rhs must be downgraded to an Int. The new behavior is consistent with the same operations in the Java programming language.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala9
1 files changed, 5 insertions, 4 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