summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-04-25 13:51:02 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2016-05-23 10:52:23 +0200
commit03d2de20047ad853d80c5c1aae68298082af27d3 (patch)
treec4afd29a2d3157173099a28ead2152a3de946180
parent2e40aa5871859b9ab6bdc03d56a81746fa90b1e5 (diff)
downloadscala-03d2de20047ad853d80c5c1aae68298082af27d3.tar.gz
scala-03d2de20047ad853d80c5c1aae68298082af27d3.tar.bz2
scala-03d2de20047ad853d80c5c1aae68298082af27d3.zip
SI-9121 test case (fixed in new optimizer), SI-9179 test case
Also adds a mising phase travel in the backend. A comment already points out why it's necessary, but it was actually forgotten.
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala2
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala31
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala23
3 files changed, 55 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index a32c21795d..a5744983b2 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -76,7 +76,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
val origOwner = sym.originalOwner
// phase travel necessary: after flatten, the name includes the name of outer classes.
// if some outer name contains $anon, a non-anon class is considered anon.
- if (delambdafyInline() && sym.rawowner.isAnonymousFunction) {
+ if (delambdafyInline() && exitingPickler(sym.rawowner.isAnonymousFunction)) {
// SI-9105: special handling for anonymous functions under delambdafy:inline.
//
// class C { def t = () => { def f { class Z } } }
diff --git a/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala
index 7954fe2360..b2ee8b3a45 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/BytecodeTest.scala
@@ -1,5 +1,6 @@
package scala.tools.nsc.backend.jvm
+import org.junit.Assert._
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@@ -137,4 +138,34 @@ class BytecodeTest extends BytecodeTesting {
Label(14), Op(ICONST_0),
Label(17), Op(IRETURN)))
}
+
+ @Test // wrong local variable table for methods containing while loops
+ def t9179(): Unit = {
+ val code =
+ """class C {
+ | def t(): Unit = {
+ | var x = ""
+ | while (x != null) {
+ | foo()
+ | x = null
+ | }
+ | bar()
+ | }
+ | def foo(): Unit = ()
+ | def bar(): Unit = ()
+ |}
+ """.stripMargin
+ val c = compileClass(code)
+ val t = getMethod(c, "t")
+ val isFrameLine = (x: Instruction) => x.isInstanceOf[FrameEntry] || x.isInstanceOf[LineNumber]
+ assertSameCode(t.instructions.filterNot(isFrameLine), List(
+ Label(0), Ldc(LDC, ""), Label(3), VarOp(ASTORE, 1),
+ Label(5), VarOp(ALOAD, 1), Jump(IFNULL, Label(21)),
+ Label(10), VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "C", "foo", "()V", false), Label(14), Op(ACONST_NULL), VarOp(ASTORE, 1), Label(18), Jump(GOTO, Label(5)),
+ Label(21), VarOp(ALOAD, 0), Invoke(INVOKEVIRTUAL, "C", "bar", "()V", false), Label(26), Op(RETURN), Label(28)))
+ val labels = t.instructions collect { case l: Label => l }
+ val x = t.localVars.find(_.name == "x").get
+ assertEquals(x.start, labels(1))
+ assertEquals(x.end, labels(7))
+ }
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
index 4e014d4529..fd020c7d93 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
@@ -1503,4 +1503,27 @@ class InlinerTest extends BytecodeTesting {
assertNoIndy(t)
assertInvoke(t, "C", "C$$$anonfun$1")
}
+
+ @Test
+ def t9121(): Unit = {
+ val codes = List(
+ """package p1
+ |object Implicits {
+ | class ScalaObservable(val underlying: Any) extends AnyVal {
+ | @inline def scMap[R](f: String): Any = f.toRx
+ | }
+ | implicit class RichFunction1[T1, R](val f: String) extends AnyVal {
+ | def toRx: Any = ""
+ | }
+ |}
+ """.stripMargin,
+ """
+ |import p1.Implicits._
+ |class C {
+ | def t(): Unit = new ScalaObservable("").scMap("")
+ |}
+ """.stripMargin)
+ val c :: _ = compileClassesSeparately(codes, extraArgs = compilerArgs)
+ assertInvoke(getMethod(c, "t"), "p1/Implicits$RichFunction1$", "toRx$extension")
+ }
}