summaryrefslogtreecommitdiff
path: root/test/junit/scala/tools/nsc/backend/jvm/opt
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2015-12-16 14:05:37 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2016-01-20 12:19:52 +0100
commit4eee5e088eb72ba00aa4b02a03a1bcf27b5d751b (patch)
tree5d2c274e965a235cc4f23e9a37f23d1ac216b2e5 /test/junit/scala/tools/nsc/backend/jvm/opt
parent118aa366782f9f27b13710122686c609c6731dfd (diff)
downloadscala-4eee5e088eb72ba00aa4b02a03a1bcf27b5d751b.tar.gz
scala-4eee5e088eb72ba00aa4b02a03a1bcf27b5d751b.tar.bz2
scala-4eee5e088eb72ba00aa4b02a03a1bcf27b5d751b.zip
Run DCE before the closure optimizer (fixes a crash)
Before identifying function callsites within the same method as a closure allocation, run DCE. The ProdCons analysis used to identify these function calls may crash if there is unreachable code, as observed in the community build with scala-js. The crash was rare because inlining, which is performed before closure optimizations, already runs DCE. However, inlining may render more code unreachable (e.g. when inlining a method that throws). Also make sure that DCE is always performed on the callee before inlining: move the DCE invocation into the inlineCallsite method, which is also invoked by the closure optimizer.
Diffstat (limited to 'test/junit/scala/tools/nsc/backend/jvm/opt')
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala19
1 files changed, 19 insertions, 0 deletions
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala
index 0f87280000..b314643fb1 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala
@@ -87,4 +87,23 @@ class ClosureOptimizerTest extends ClearAfterClass {
TypeOp(CHECKCAST, "java/lang/String"), Invoke(INVOKESTATIC, "C", "C$$$anonfun$1", "(Ljava/lang/String;)Ljava/lang/String;", false),
Op(ARETURN)))
}
+
+ @Test
+ def closureOptWithUnreachableCode(): Unit = {
+ // this example used to crash the ProdCons analysis in the closure optimizer - ProdCons
+ // expects no unreachable code.
+ val code =
+ """class C {
+ | @inline final def m = throw new Error("")
+ | def t = {
+ | val f = (x: Int) => x + 1
+ | m
+ | f(10) // unreachable after inlining m
+ | }
+ |}
+ """.stripMargin
+ val List(c) = compileClasses(compiler)(code)
+ assertEquals(getSingleMethod(c, "t").instructions.summary,
+ List(NEW, DUP, LDC, "<init>", ATHROW))
+ }
}