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 | 2 | ||||
-rw-r--r-- | test/files/run/t8601c.flags | 1 | ||||
-rw-r--r-- | test/files/run/t8601c.scala | 12 |
4 files changed, 6 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala index 0b943360de..c49f23852f 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala @@ -56,10 +56,11 @@ abstract class ClosureElimination extends SubComponent { case (BOX(t1), UNBOX(t2)) if (t1 == t2) => Some(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 (LOAD_FIELD(sym, isStatic), DROP(_)) if !sym.hasAnnotation(definitions.VolatileAttr) => + if (isStatic) + Some(Nil) + else + Some(DROP(REFERENCE(definitions.ObjectClass)) :: Nil) 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 64aed19bf0..3c983e6fdf 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -167,7 +167,7 @@ abstract class DeadCodeElimination extends SubComponent { set += idx localStores(key) = set - case RETURN(_) | JUMP(_) | CJUMP(_, _, _, _) | CZJUMP(_, _, _, _) | STORE_FIELD(_, _) | LOAD_FIELD(_, _) | // Why LOAD_FIELD? It can NPE! + case RETURN(_) | JUMP(_) | CJUMP(_, _, _, _) | CZJUMP(_, _, _, _) | STORE_FIELD(_, _) | THROW(_) | LOAD_ARRAY_ITEM(_) | STORE_ARRAY_ITEM(_) | SCOPE_ENTER(_) | SCOPE_EXIT(_) | STORE_THIS(_) | LOAD_EXCEPTION(_) | SWITCH(_, _) | MONITOR_ENTER() | MONITOR_EXIT() | CHECK_CAST(_) => moveToWorkList() diff --git a/test/files/run/t8601c.flags b/test/files/run/t8601c.flags deleted file mode 100644 index 1182725e86..0000000000 --- a/test/files/run/t8601c.flags +++ /dev/null @@ -1 +0,0 @@ --optimize
\ No newline at end of file diff --git a/test/files/run/t8601c.scala b/test/files/run/t8601c.scala deleted file mode 100644 index c487d6825e..0000000000 --- a/test/files/run/t8601c.scala +++ /dev/null @@ -1,12 +0,0 @@ -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)) - - } -} |