diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2015-12-16 14:05:37 +0100 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2016-01-20 12:19:52 +0100 |
commit | 4eee5e088eb72ba00aa4b02a03a1bcf27b5d751b (patch) | |
tree | 5d2c274e965a235cc4f23e9a37f23d1ac216b2e5 /test | |
parent | 118aa366782f9f27b13710122686c609c6731dfd (diff) | |
download | scala-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')
-rw-r--r-- | test/junit/scala/tools/nsc/backend/jvm/opt/ClosureOptimizerTest.scala | 19 |
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)) + } } |