summaryrefslogtreecommitdiff
path: root/test/files/run/t9422.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2015-07-29 13:29:57 +1000
committerJason Zaugg <jzaugg@gmail.com>2015-07-29 14:13:22 +1000
commitec95e534a213a6ea760aa31c507d122ce449890a (patch)
tree26683be8f4c387085d7ce7a2ddf8586ee609087c /test/files/run/t9422.scala
parent0e9525aa618a2eca143a1c7379ff1e6efd23b86e (diff)
downloadscala-ec95e534a213a6ea760aa31c507d122ce449890a.tar.gz
scala-ec95e534a213a6ea760aa31c507d122ce449890a.tar.bz2
scala-ec95e534a213a6ea760aa31c507d122ce449890a.zip
SI-9422 Fix incorrect constant propagation
The ConstantOptimization phase uses abstract interpretation to track what is known about values, and then to use this information to optimize away tests with a statically known result. Constant propagation was added under -optimize in Scala 2.11.0-M3, in PR #2214. For example, we might know that a variable must hold one of a set of values (`Possible`). Or, we could track that it must *not* be of of a set of value (`Impossible`). The test case in the bug report was enough to create comparison: v1 == v2 // where V1 = Possible(Set(true, false)) // V2 = Possible(Set(true, false)) This test was considered to be always true, due to a bug in `Possible#mightNotEqual`. The only time we can be sure that `Possible(p1) mightNotEquals Possible(p2)` is if `p1` and `p2` are the same singleton set. This commit changes this method to implement this logic. The starting assumption for all values is currently `Impossible(Set())`, although it would also be reasonable to represent an unknown boolean variable as `Possible(Set(true, false))`, given the finite and small domain. I tried to change the starting assumption for boolean locals in exactly this manner, and that brings the bug into sharp focus. Under this patch: https://github.com/retronym/scala/commit/e564fe522d This code: def test(a: Boolean, b: Boolean) = a == b Compiles to: public boolean test(boolean, boolean); Code: 0: iconst_1 1: ireturn Note: the enclosed test case does not list `-optimize` in a `.flags` file, I'm relying on that being passed in by the validation build. I've tested locally with that option, though.
Diffstat (limited to 'test/files/run/t9422.scala')
-rw-r--r--test/files/run/t9422.scala11
1 files changed, 11 insertions, 0 deletions
diff --git a/test/files/run/t9422.scala b/test/files/run/t9422.scala
new file mode 100644
index 0000000000..5ca2e8daaa
--- /dev/null
+++ b/test/files/run/t9422.scala
@@ -0,0 +1,11 @@
+class Test(val x: Long) {
+ def sameDirection(y: Long): Boolean =
+ (y == 0 || x == 0 || ((y > 0) == (x > 0)))
+}
+
+object Test {
+ def main(args: Array[String]) {
+ val b = new Test(1L)
+ assert(!b.sameDirection(-1L))
+ }
+}