diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala | 9 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala | 6 | ||||
-rw-r--r-- | test/files/run/t8601.flags | 1 | ||||
-rw-r--r-- | test/files/run/t8601.scala | 15 | ||||
-rw-r--r-- | test/files/run/t8601b.flags | 1 | ||||
-rw-r--r-- | test/files/run/t8601b.scala | 14 | ||||
-rw-r--r-- | test/files/run/t8601c.flags | 1 | ||||
-rw-r--r-- | test/files/run/t8601c.scala | 12 | ||||
-rw-r--r-- | test/files/run/t8601d.flags | 1 | ||||
-rw-r--r-- | test/files/run/t8601d.scala | 8 |
10 files changed, 61 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala index c49f23852f..0b943360de 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala @@ -56,11 +56,10 @@ abstract class ClosureElimination extends SubComponent { case (BOX(t1), UNBOX(t2)) if (t1 == t2) => Some(Nil) - case (LOAD_FIELD(sym, isStatic), DROP(_)) if !sym.hasAnnotation(definitions.VolatileAttr) => - if (isStatic) - Some(Nil) - else - Some(DROP(REFERENCE(definitions.ObjectClass)) :: Nil) + // Can't eliminate (LOAD_FIELD, DROP) without eliding side effects: + // - static class initialization + // - NPE if the receiver is null + // We could replace the LOAD/DROP with a null check to preserve semantics. case _ => None } diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index 90c37ba0b3..245894a4af 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -167,9 +167,9 @@ abstract class DeadCodeElimination extends SubComponent { set += idx localStores(key) = set - case RETURN(_) | JUMP(_) | CJUMP(_, _, _, _) | CZJUMP(_, _, _, _) | STORE_FIELD(_, _) | + case RETURN(_) | JUMP(_) | CJUMP(_, _, _, _) | CZJUMP(_, _, _, _) | STORE_FIELD(_, _) | LOAD_FIELD(_, _) | // Why LOAD_FIELD? It can NPE! THROW(_) | LOAD_ARRAY_ITEM(_) | STORE_ARRAY_ITEM(_) | SCOPE_ENTER(_) | SCOPE_EXIT(_) | STORE_THIS(_) | - LOAD_EXCEPTION(_) | SWITCH(_, _) | MONITOR_ENTER() | MONITOR_EXIT() | CHECK_CAST(_) => + LOAD_EXCEPTION(_) | SWITCH(_, _) | MONITOR_ENTER() | MONITOR_EXIT() | CHECK_CAST(_) | CREATE_ARRAY(_, _) => moveToWorkList() case CALL_METHOD(m1, _) if isSideEffecting(m1) => @@ -193,6 +193,8 @@ abstract class DeadCodeElimination extends SubComponent { moveToWorkListIf(necessary) case LOAD_MODULE(sym) if isLoadNeeded(sym) => moveToWorkList() // SI-4859 Module initialization might side-effect. + case CALL_PRIMITIVE(Arithmetic(DIV | REM, INT | LONG) | ArrayLength(_)) => + moveToWorkList() // SI-8601 Might divide by zero case _ => () moveToWorkListIf(cond = false) } diff --git a/test/files/run/t8601.flags b/test/files/run/t8601.flags new file mode 100644 index 0000000000..1182725e86 --- /dev/null +++ b/test/files/run/t8601.flags @@ -0,0 +1 @@ +-optimize
\ No newline at end of file diff --git a/test/files/run/t8601.scala b/test/files/run/t8601.scala new file mode 100644 index 0000000000..e1afc23cc4 --- /dev/null +++ b/test/files/run/t8601.scala @@ -0,0 +1,15 @@ +object Test { + def idiv(x: Int): Unit = x / 0 + def ldiv(x: Long): Unit = x / 0 + def irem(x: Int): Unit = x % 0 + def lrem(x: Long): Unit = x % 0 + + def check(x: => Any) = try { x; sys.error("failed to throw divide by zero!") } catch { case _: ArithmeticException => } + + def main(args: Array[String]) { + check(idiv(1)) + check(ldiv(1L)) + check(irem(1)) + check(lrem(1L)) + } +} diff --git a/test/files/run/t8601b.flags b/test/files/run/t8601b.flags new file mode 100644 index 0000000000..1182725e86 --- /dev/null +++ b/test/files/run/t8601b.flags @@ -0,0 +1 @@ +-optimize
\ No newline at end of file diff --git a/test/files/run/t8601b.scala b/test/files/run/t8601b.scala new file mode 100644 index 0000000000..9c37ce33d6 --- /dev/null +++ b/test/files/run/t8601b.scala @@ -0,0 +1,14 @@ +object Test { + def len(x: Array[String]): Unit = x.length + def load(x: Array[String]): Unit = x(0) + def newarray(i: Int): Unit = new Array[Int](i) + + def check(x: => Any) = try { x; sys.error("failed to throw NPE!") } catch { case _: NullPointerException => } + def checkNegSize(x: => Any) = try { x; sys.error("failed to throw NegativeArraySizeException!") } catch { case _: NegativeArraySizeException => } + + def main(args: Array[String]) { + check(len(null)) // bug: did not NPE + check(load(null)) + checkNegSize(newarray(-1)) + } +} diff --git a/test/files/run/t8601c.flags b/test/files/run/t8601c.flags new file mode 100644 index 0000000000..1182725e86 --- /dev/null +++ b/test/files/run/t8601c.flags @@ -0,0 +1 @@ +-optimize
\ No newline at end of file diff --git a/test/files/run/t8601c.scala b/test/files/run/t8601c.scala new file mode 100644 index 0000000000..c487d6825e --- /dev/null +++ b/test/files/run/t8601c.scala @@ -0,0 +1,12 @@ +object Test { + def loadField(x: scala.runtime.IntRef): Unit = x.elem + def storeField(x: scala.runtime.IntRef): Unit = x.elem = 42 + + def check(x: => Any) = try { x; sys.error("failed to throw NPE!") } catch { case _: NullPointerException => } + + def main(args: Array[String]) { + check(loadField(null)) // bug: did not NPE under -Ydead-code + check(storeField(null)) + + } +} diff --git a/test/files/run/t8601d.flags b/test/files/run/t8601d.flags new file mode 100644 index 0000000000..1182725e86 --- /dev/null +++ b/test/files/run/t8601d.flags @@ -0,0 +1 @@ +-optimize
\ No newline at end of file diff --git a/test/files/run/t8601d.scala b/test/files/run/t8601d.scala new file mode 100644 index 0000000000..ac89963d67 --- /dev/null +++ b/test/files/run/t8601d.scala @@ -0,0 +1,8 @@ +object Test { + def monitor(x: AnyRef): Unit = {x.synchronized(()); ()} + def check(x: => Any) = try { x; sys.error("failed to throw NPE") } catch { case _: NullPointerException => } + + def main(args: Array[String]) { + check(monitor(null)) + } +} |