summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@typesafe.com>2016-02-03 16:24:35 +0100
committerLukas Rytz <lukas.rytz@typesafe.com>2016-02-03 16:24:35 +0100
commitb1981c0358ada039578dc857bb24c6c81db37bf7 (patch)
treed1212e3335ac0e9a78dcdfeabddea2e0734b2968 /test
parent2c78fb31c9f34ccfe262d7b8660c9e486424823a (diff)
parent4af9f1566dde56adecdba2690df71e39552e32fe (diff)
downloadscala-b1981c0358ada039578dc857bb24c6c81db37bf7.tar.gz
scala-b1981c0358ada039578dc857bb24c6c81db37bf7.tar.bz2
scala-b1981c0358ada039578dc857bb24c6c81db37bf7.zip
Merge pull request #4920 from lrytz/oldOptimizerTests
restore / rewrite various tests
Diffstat (limited to 'test')
-rw-r--r--test/files/jvm/t6941.check1
-rw-r--r--test/files/jvm/t6941.flags1
-rw-r--r--test/files/jvm/t6941/Analyzed_1.flags1
-rw-r--r--test/files/jvm/t6941/Analyzed_1.scala11
-rw-r--r--test/files/jvm/t6941/test.scala15
-rw-r--r--test/files/pos/t2171.flags1
-rw-r--r--test/files/pos/t2171.scala7
-rw-r--r--test/files/pos/t3252.flags1
-rw-r--r--test/files/pos/t3252.scala15
-rw-r--r--test/files/pos/t3420.flags2
-rw-r--r--test/files/pos/t3430.flags1
-rw-r--r--test/files/pos/t3430.scala13
-rw-r--r--test/files/pos/t4579.flags1
-rw-r--r--test/files/pos/t4840.flags2
-rw-r--r--test/files/pos/t6157.flags1
-rw-r--r--test/files/pos/t6157.scala25
-rw-r--r--test/files/pos/t6547.flags1
-rw-r--r--test/files/pos/t6547.scala6
-rw-r--r--test/files/pos/t8062.flags1
-rw-r--r--test/files/pos/t8062/A_1.scala5
-rw-r--r--test/files/pos/t8062/B_2.scala3
-rw-r--r--test/files/pos/t8306.flags1
-rw-r--r--test/files/pos/t8306.scala8
-rw-r--r--test/files/pos/t8359-closelim-crash.flags1
-rw-r--r--test/files/pos/t8359-closelim-crash.scala23
-rw-r--r--test/files/pos/t9123.flags1
-rw-r--r--test/files/pos/t9123.scala10
-rw-r--r--test/files/pos/trait-force-info.flags1
-rw-r--r--test/files/pos/trait-force-info.scala18
-rw-r--r--test/files/run/elidable-opt.scala3
-rw-r--r--test/files/run/lisp.check26
-rw-r--r--test/files/run/lisp.scala (renamed from test/files/pos/t4579.scala)2
-rw-r--r--test/files/run/t7008-scala-defined.flags0
-rw-r--r--test/files/run/t7008-scala-defined/Test_3.scala3
-rw-r--r--test/files/run/t7582.check5
-rw-r--r--test/files/run/t7582.flags2
-rw-r--r--test/files/run/t7582/InlineHolder.scala3
-rw-r--r--test/files/run/t7582b.check5
-rw-r--r--test/files/run/t7582b.flags2
-rw-r--r--test/files/run/t7582b/InlineHolder.scala3
-rw-r--r--test/files/run/t7807.check3
-rw-r--r--test/files/run/t7807.scala21
-rw-r--r--test/junit/scala/issues/OptimizedBytecodeTest.scala331
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala6
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala23
-rw-r--r--test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala25
-rw-r--r--test/pending/run/private-inline.check13
-rw-r--r--test/pending/run/private-inline.flags1
-rw-r--r--test/pending/run/private-inline.scala52
49 files changed, 444 insertions, 262 deletions
diff --git a/test/files/jvm/t6941.check b/test/files/jvm/t6941.check
deleted file mode 100644
index 43f53aba12..0000000000
--- a/test/files/jvm/t6941.check
+++ /dev/null
@@ -1 +0,0 @@
-bytecode identical
diff --git a/test/files/jvm/t6941.flags b/test/files/jvm/t6941.flags
deleted file mode 100644
index 49d036a887..0000000000
--- a/test/files/jvm/t6941.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimize
diff --git a/test/files/jvm/t6941/Analyzed_1.flags b/test/files/jvm/t6941/Analyzed_1.flags
deleted file mode 100644
index ad51758c39..0000000000
--- a/test/files/jvm/t6941/Analyzed_1.flags
+++ /dev/null
@@ -1 +0,0 @@
--nowarn
diff --git a/test/files/jvm/t6941/Analyzed_1.scala b/test/files/jvm/t6941/Analyzed_1.scala
deleted file mode 100644
index b6951f71ee..0000000000
--- a/test/files/jvm/t6941/Analyzed_1.scala
+++ /dev/null
@@ -1,11 +0,0 @@
-// this class's bytecode, compiled under -optimize is analyzed by the test
-// method a's bytecode should be identical to method b's bytecode
-class SameBytecode {
- def a(xs: List[Int]) = xs match {
- case x :: _ => x
- }
-
- def b(xs: List[Int]) = xs match {
- case xs: ::[Int] => xs.head
- }
-} \ No newline at end of file
diff --git a/test/files/jvm/t6941/test.scala b/test/files/jvm/t6941/test.scala
deleted file mode 100644
index fceb54487f..0000000000
--- a/test/files/jvm/t6941/test.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-import scala.tools.partest.{BytecodeTest, ASMConverters}
-
-import scala.tools.nsc.util.JavaClassPath
-import java.io.InputStream
-import scala.tools.asm
-import asm.ClassReader
-import asm.tree.{ClassNode, InsnList}
-import scala.collection.JavaConverters._
-
-object Test extends BytecodeTest {
- def show: Unit = {
- val classNode = loadClassNode("SameBytecode")
- similarBytecode(getMethod(classNode, "a"), getMethod(classNode, "b"), ASMConverters.equivalentBytecode(_, _))
- }
-}
diff --git a/test/files/pos/t2171.flags b/test/files/pos/t2171.flags
deleted file mode 100644
index eb4d19bcb9..0000000000
--- a/test/files/pos/t2171.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimise \ No newline at end of file
diff --git a/test/files/pos/t2171.scala b/test/files/pos/t2171.scala
deleted file mode 100644
index 6c754c76a6..0000000000
--- a/test/files/pos/t2171.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-final object test {
- def logIgnoredException(msg: => String) =
- try 0 catch { case ex => println(msg) }
-
- def main (args: Array[String]): Unit =
- while (true) logIgnoredException ("...")
-}
diff --git a/test/files/pos/t3252.flags b/test/files/pos/t3252.flags
deleted file mode 100644
index eb4d19bcb9..0000000000
--- a/test/files/pos/t3252.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimise \ No newline at end of file
diff --git a/test/files/pos/t3252.scala b/test/files/pos/t3252.scala
deleted file mode 100644
index 3ecc1e7cef..0000000000
--- a/test/files/pos/t3252.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-class A {
- def f(x : Boolean) : Thread = {
- g {
- x match {
- case false =>
- B.h { }
- }
- }
- }
-
- private def g[T](block : => T) = sys.error("")
-}
-object B {
- def h(block : => Unit) : Nothing = sys.error("")
-}
diff --git a/test/files/pos/t3420.flags b/test/files/pos/t3420.flags
index 4fbafb7e80..397969bb1d 100644
--- a/test/files/pos/t3420.flags
+++ b/test/files/pos/t3420.flags
@@ -1 +1 @@
--Yopt-warnings Yopt:l:project -Xfatal-warnings \ No newline at end of file
+-Yopt-warnings -Yopt:l:classpath -Xfatal-warnings \ No newline at end of file
diff --git a/test/files/pos/t3430.flags b/test/files/pos/t3430.flags
deleted file mode 100644
index eb4d19bcb9..0000000000
--- a/test/files/pos/t3430.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimise \ No newline at end of file
diff --git a/test/files/pos/t3430.scala b/test/files/pos/t3430.scala
deleted file mode 100644
index 3129c6276a..0000000000
--- a/test/files/pos/t3430.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-// package com.example
-
-object A {
- def f1(f: String => Boolean) = f("a")
-
- def f2(): Boolean =
- f1 { s1 =>
- f1 { s2 =>
- while (true) { }
- true
- }
- }
-} \ No newline at end of file
diff --git a/test/files/pos/t4579.flags b/test/files/pos/t4579.flags
deleted file mode 100644
index 1182725e86..0000000000
--- a/test/files/pos/t4579.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimize \ No newline at end of file
diff --git a/test/files/pos/t4840.flags b/test/files/pos/t4840.flags
index eb4d19bcb9..422d6be431 100644
--- a/test/files/pos/t4840.flags
+++ b/test/files/pos/t4840.flags
@@ -1 +1 @@
--optimise \ No newline at end of file
+-Yopt:l:classpath \ No newline at end of file
diff --git a/test/files/pos/t6157.flags b/test/files/pos/t6157.flags
deleted file mode 100644
index 0ebca3e7af..0000000000
--- a/test/files/pos/t6157.flags
+++ /dev/null
@@ -1 +0,0 @@
- -optimize
diff --git a/test/files/pos/t6157.scala b/test/files/pos/t6157.scala
deleted file mode 100644
index 7463989b14..0000000000
--- a/test/files/pos/t6157.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-// SI-6157 - Compiler crash on inlined function and -optimize option
-
-object Test {
- def main(args: Array[String]) {
- Console.println(
- ErrorHandler.defaultIfIOException("String")("String")
- )
- }
-}
-
-import java.io.IOException
-
-object ErrorHandler {
-
- @inline
- def defaultIfIOException[T](default: => T)(closure: => T): T = {
- try {
- closure
- } catch {
- case e: IOException =>
- default
- }
- }
-}
-
diff --git a/test/files/pos/t6547.flags b/test/files/pos/t6547.flags
deleted file mode 100644
index c9b68d70dc..0000000000
--- a/test/files/pos/t6547.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimise
diff --git a/test/files/pos/t6547.scala b/test/files/pos/t6547.scala
deleted file mode 100644
index 53bd798219..0000000000
--- a/test/files/pos/t6547.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-trait ConfigurableDefault[@specialized V] {
- def fillArray(arr: Array[V], v: V) = (arr: Any) match {
- case x: Array[Int] => null
- case x: Array[Long] => v.asInstanceOf[Long]
- }
-}
diff --git a/test/files/pos/t8062.flags b/test/files/pos/t8062.flags
deleted file mode 100644
index 49d036a887..0000000000
--- a/test/files/pos/t8062.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimize
diff --git a/test/files/pos/t8062/A_1.scala b/test/files/pos/t8062/A_1.scala
deleted file mode 100644
index ca0411dae8..0000000000
--- a/test/files/pos/t8062/A_1.scala
+++ /dev/null
@@ -1,5 +0,0 @@
-package warmup
-
-object Warmup {
- def filter[A](p: Any => Boolean): Any = filter[Any](p)
-}
diff --git a/test/files/pos/t8062/B_2.scala b/test/files/pos/t8062/B_2.scala
deleted file mode 100644
index f0a6761488..0000000000
--- a/test/files/pos/t8062/B_2.scala
+++ /dev/null
@@ -1,3 +0,0 @@
-object Test {
- warmup.Warmup.filter[Any](x => false)
-}
diff --git a/test/files/pos/t8306.flags b/test/files/pos/t8306.flags
deleted file mode 100644
index 49d036a887..0000000000
--- a/test/files/pos/t8306.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimize
diff --git a/test/files/pos/t8306.scala b/test/files/pos/t8306.scala
deleted file mode 100644
index e04b054eb9..0000000000
--- a/test/files/pos/t8306.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-class Si8306 {
- def foo: Int = 123
- lazy val extension: Int =
- foo match {
- case idx if idx != -1 => 15
- case _ => 17
- }
-}
diff --git a/test/files/pos/t8359-closelim-crash.flags b/test/files/pos/t8359-closelim-crash.flags
deleted file mode 100644
index 49d036a887..0000000000
--- a/test/files/pos/t8359-closelim-crash.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimize
diff --git a/test/files/pos/t8359-closelim-crash.scala b/test/files/pos/t8359-closelim-crash.scala
deleted file mode 100644
index 1413694d10..0000000000
--- a/test/files/pos/t8359-closelim-crash.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-package test
-
-// This is a minimization of code that crashed the compiler during bootstrapping
-// in the first iteration of https://github.com/scala/scala/pull/4373, the PR
-// that adjusted the order of free and declared params in LambdaLift.
-
-// Was:
-// java.lang.AssertionError: assertion failed:
-// Record Record(<$anon: Function1>,Map(value a$1 -> Deref(LocalVar(value b)))) does not contain a field value b$1
-// at scala.tools.nsc.Global.assert(Global.scala:262)
-// at scala.tools.nsc.backend.icode.analysis.CopyPropagation$copyLattice$State.getFieldNonRecordValue(CopyPropagation.scala:113)
-// at scala.tools.nsc.backend.icode.analysis.CopyPropagation$copyLattice$State.getFieldNonRecordValue(CopyPropagation.scala:122)
-// at scala.tools.nsc.backend.opt.ClosureElimination$ClosureElim$$anonfun$analyzeMethod$1$$anonfun$apply$2.replaceFieldAccess$1(ClosureElimination.scala:124)
-class Typer {
- def bar(a: Boolean, b: Boolean): Unit = {
- @inline
- def baz(): Unit = {
- ((_: Any) => (Typer.this, a, b)).apply("")
- }
- ((_: Any) => baz()).apply("")
- }
-}
-
diff --git a/test/files/pos/t9123.flags b/test/files/pos/t9123.flags
deleted file mode 100644
index c16e2f71dc..0000000000
--- a/test/files/pos/t9123.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimize -Ydelambdafy:method
diff --git a/test/files/pos/t9123.scala b/test/files/pos/t9123.scala
deleted file mode 100644
index 22d55b4351..0000000000
--- a/test/files/pos/t9123.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-trait Setting {
- type T
- def value: T
-}
-
-object Test {
- def test(x: Some[Setting]) = x match {
- case Some(dep) => Some(dep.value) map (_ => true)
- }
-}
diff --git a/test/files/pos/trait-force-info.flags b/test/files/pos/trait-force-info.flags
deleted file mode 100644
index eb4d19bcb9..0000000000
--- a/test/files/pos/trait-force-info.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimise \ No newline at end of file
diff --git a/test/files/pos/trait-force-info.scala b/test/files/pos/trait-force-info.scala
deleted file mode 100644
index c2b33869c3..0000000000
--- a/test/files/pos/trait-force-info.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-/** This does NOT crash unless it's in the interactive package.
- */
-
-package scala.tools.nsc
-package interactive
-
-trait MyContextTrees {
- val self: Global
- val NoContext = self.analyzer.NoContext
-}
-//
-// error: java.lang.AssertionError: assertion failed: trait Contexts.NoContext$ linkedModule: <none>List()
-// at scala.Predef$.assert(Predef.scala:160)
-// at scala.tools.nsc.symtab.classfile.ClassfileParser$innerClasses$.innerSymbol$1(ClassfileParser.scala:1211)
-// at scala.tools.nsc.symtab.classfile.ClassfileParser$innerClasses$.classSymbol(ClassfileParser.scala:1223)
-// at scala.tools.nsc.symtab.classfile.ClassfileParser.classNameToSymbol(ClassfileParser.scala:489)
-// at scala.tools.nsc.symtab.classfile.ClassfileParser.sig2type$1(ClassfileParser.scala:757)
-// at scala.tools.nsc.symtab.classfile.ClassfileParser.sig2type$1(ClassfileParser.scala:789)
diff --git a/test/files/run/elidable-opt.scala b/test/files/run/elidable-opt.scala
index ebada46de8..a2f29d2caf 100644
--- a/test/files/run/elidable-opt.scala
+++ b/test/files/run/elidable-opt.scala
@@ -1,6 +1,3 @@
-/*
- * filter: inliner warnings; re-run with
- */
import annotation._
import elidable._
diff --git a/test/files/run/lisp.check b/test/files/run/lisp.check
new file mode 100644
index 0000000000..64053f26d0
--- /dev/null
+++ b/test/files/run/lisp.check
@@ -0,0 +1,26 @@
+(lambda (x) (+ (* x x) 1))
+(lambda (x) (+ (* x x) 1))
+
+( '(1 2 3)) = (1 2 3)
+(car '(1 2 3)) = 1
+(cdr '(1 2 3)) = (2 3)
+(null? '(2 3)) = 0
+(null? '()) = 1
+
+faculty(10) = 3628800
+faculty(10) = 3628800
+foobar = ("a" "bc" "def" "z")
+
+List('lambda, List('x), List('+, List('*, 'x, 'x), 1))
+(lambda (x) (+ (* x x) 1))
+
+( '(1 2 3)) = (1 2 3)
+(car '(1 2 3)) = 1
+(cdr '(1 2 3)) = (2 3)
+(null? '(2 3)) = 0
+(null? '()) = 1
+
+faculty(10) = 3628800
+faculty(10) = 3628800
+foobar = ("a" "bc" "def" "z")
+
diff --git a/test/files/pos/t4579.scala b/test/files/run/lisp.scala
index cd1553f02a..162c7d2599 100644
--- a/test/files/pos/t4579.scala
+++ b/test/files/run/lisp.scala
@@ -1,5 +1,5 @@
//############################################################################
-// Lisp interpreter (revived as an optimizer test.)
+// Lisp interpreter
//############################################################################
//############################################################################
diff --git a/test/files/run/t7008-scala-defined.flags b/test/files/run/t7008-scala-defined.flags
deleted file mode 100644
index e69de29bb2..0000000000
--- a/test/files/run/t7008-scala-defined.flags
+++ /dev/null
diff --git a/test/files/run/t7008-scala-defined/Test_3.scala b/test/files/run/t7008-scala-defined/Test_3.scala
index 26178142ab..ee7b9d9cde 100644
--- a/test/files/run/t7008-scala-defined/Test_3.scala
+++ b/test/files/run/t7008-scala-defined/Test_3.scala
@@ -1,6 +1,3 @@
-/*
- * filter: inliner warning; re-run with
- */
import scala.reflect.runtime.universe._
object Test extends App {
diff --git a/test/files/run/t7582.check b/test/files/run/t7582.check
index 0cfbf08886..58d0f19f5d 100644
--- a/test/files/run/t7582.check
+++ b/test/files/run/t7582.check
@@ -1 +1,6 @@
+InlineHolder.scala:9: warning: p1/InlineHolder$::inlinable()I is annotated @inline but could not be inlined:
+The callee p1/InlineHolder$::inlinable()I contains the instruction INVOKESTATIC p1/PackageProtectedJava.protectedMethod ()I
+that would cause an IllegalAccessError when inlined into class O$.
+ def x = p1.InlineHolder.inlinable
+ ^
2
diff --git a/test/files/run/t7582.flags b/test/files/run/t7582.flags
index 422d6be431..1f45833eff 100644
--- a/test/files/run/t7582.flags
+++ b/test/files/run/t7582.flags
@@ -1 +1 @@
--Yopt:l:classpath \ No newline at end of file
+-Yopt:l:classpath -Yopt-warnings \ No newline at end of file
diff --git a/test/files/run/t7582/InlineHolder.scala b/test/files/run/t7582/InlineHolder.scala
index 3cbf233ce1..a18b9effaa 100644
--- a/test/files/run/t7582/InlineHolder.scala
+++ b/test/files/run/t7582/InlineHolder.scala
@@ -1,6 +1,3 @@
-/*
- * filter: inliner warning; re-run with
- */
package p1 {
object InlineHolder {
@inline def inlinable = p1.PackageProtectedJava.protectedMethod() + 1
diff --git a/test/files/run/t7582b.check b/test/files/run/t7582b.check
index 0cfbf08886..58d0f19f5d 100644
--- a/test/files/run/t7582b.check
+++ b/test/files/run/t7582b.check
@@ -1 +1,6 @@
+InlineHolder.scala:9: warning: p1/InlineHolder$::inlinable()I is annotated @inline but could not be inlined:
+The callee p1/InlineHolder$::inlinable()I contains the instruction INVOKESTATIC p1/PackageProtectedJava.protectedMethod ()I
+that would cause an IllegalAccessError when inlined into class O$.
+ def x = p1.InlineHolder.inlinable
+ ^
2
diff --git a/test/files/run/t7582b.flags b/test/files/run/t7582b.flags
index 422d6be431..1f45833eff 100644
--- a/test/files/run/t7582b.flags
+++ b/test/files/run/t7582b.flags
@@ -1 +1 @@
--Yopt:l:classpath \ No newline at end of file
+-Yopt:l:classpath -Yopt-warnings \ No newline at end of file
diff --git a/test/files/run/t7582b/InlineHolder.scala b/test/files/run/t7582b/InlineHolder.scala
index 3cbf233ce1..a18b9effaa 100644
--- a/test/files/run/t7582b/InlineHolder.scala
+++ b/test/files/run/t7582b/InlineHolder.scala
@@ -1,6 +1,3 @@
-/*
- * filter: inliner warning; re-run with
- */
package p1 {
object InlineHolder {
@inline def inlinable = p1.PackageProtectedJava.protectedMethod() + 1
diff --git a/test/files/run/t7807.check b/test/files/run/t7807.check
new file mode 100644
index 0000000000..fd22077f2e
--- /dev/null
+++ b/test/files/run/t7807.check
@@ -0,0 +1,3 @@
+...
+...
+...
diff --git a/test/files/run/t7807.scala b/test/files/run/t7807.scala
new file mode 100644
index 0000000000..8e3099ec14
--- /dev/null
+++ b/test/files/run/t7807.scala
@@ -0,0 +1,21 @@
+object Test {
+ def main(args: Array[String]) {
+ try {
+ println("...")
+ }
+ finally {
+ try {
+ println("...")
+ }
+ finally {
+ try {
+ println("...")
+ }
+ catch {
+ case ct: scala.util.control.ControlThrowable => throw(ct)
+ case t: Throwable => t.printStackTrace()
+ }
+ }
+ }
+ }
+}
diff --git a/test/junit/scala/issues/OptimizedBytecodeTest.scala b/test/junit/scala/issues/OptimizedBytecodeTest.scala
new file mode 100644
index 0000000000..3c6f1ff25e
--- /dev/null
+++ b/test/junit/scala/issues/OptimizedBytecodeTest.scala
@@ -0,0 +1,331 @@
+package scala.issues
+
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import org.junit.Test
+import scala.tools.asm.Opcodes._
+import org.junit.Assert._
+
+import scala.tools.nsc.backend.jvm.{AsmUtils, CodeGenTools}
+
+import CodeGenTools._
+import scala.tools.partest.ASMConverters
+import ASMConverters._
+import AsmUtils._
+
+import scala.tools.testing.ClearAfterClass
+
+object OptimizedBytecodeTest extends ClearAfterClass.Clearable {
+ val args = "-Yopt:l:classpath -Yopt-warnings"
+ var compiler = newCompiler(extraArgs = args)
+ def clear(): Unit = { compiler = null }
+}
+
+@RunWith(classOf[JUnit4])
+class OptimizedBytecodeTest extends ClearAfterClass {
+ ClearAfterClass.stateToClear = OptimizedBytecodeTest
+
+ val compiler = OptimizedBytecodeTest.compiler
+
+ @Test
+ def t2171(): Unit = {
+ val code =
+ """class C {
+ | final def m(msg: => String) = try 0 catch { case ex: Throwable => println(msg) }
+ | def t(): Unit = while (true) m("...")
+ |}
+ """.stripMargin
+ val List(c) = compileClasses(compiler)(code)
+ assertSameCode(getSingleMethod(c, "t").instructions.dropNonOp, List(Label(0), Jump(GOTO, Label(0))))
+ }
+
+ @Test
+ def t3430(): Unit = {
+ val code =
+ """class C {
+ | final def m(f: String => Boolean) = f("a")
+ | def t(): Boolean =
+ | m { s1 =>
+ | m { s2 =>
+ | while (true) { }
+ | true
+ | }
+ | }
+ |}
+ """.stripMargin
+ val List(c) = compileClasses(compiler)(code)
+
+ assertEquals(
+ getSingleMethod(c, "t").instructions.summary,
+ List(LDC, ASTORE, ALOAD /*0*/, ALOAD /*1*/, "C$$$anonfun$1", IRETURN))
+
+ assertEquals(
+ getSingleMethod(c, "C$$$anonfun$1").instructions.summary,
+ List(LDC, "C$$$anonfun$2", IRETURN))
+
+ assertEquals(
+ getSingleMethod(c, "C$$$anonfun$2").instructions.summary,
+ List(-1 /*A*/, GOTO /*A*/))
+ }
+
+ @Test
+ def t3252(): Unit = {
+ val code =
+ """class C {
+ | def t(x: Boolean): Thread = {
+ | g {
+ | x match {
+ | case false => Tat.h { }
+ | }
+ | }
+ | }
+ |
+ | private def g[T](block: => T) = ???
+ |}
+ |object Tat {
+ | def h(block: => Unit): Nothing = ???
+ |}
+ """.stripMargin
+ val List(c, t, tMod) = compileClasses(compiler)(code, allowMessage = _.msg.contains("not be exhaustive"))
+ assertEquals(
+ getSingleMethod(c, "t").instructions.summary,
+ List(GETSTATIC, "$qmark$qmark$qmark", ATHROW))
+ }
+
+ @Test
+ def t6157(): Unit = {
+ val code =
+ """class C {
+ | def t = println(ErrorHandler.defaultIfIOException("String")("String"))
+ |}
+ |object ErrorHandler {
+ | import java.io.IOException
+ | @inline
+ | def defaultIfIOException[T](default: => T)(closure: => T): T = try closure catch {
+ | case e: IOException => default
+ | }
+ |}
+ """.stripMargin
+
+ val msg =
+ """ErrorHandler$::defaultIfIOException(Lscala/Function0;Lscala/Function0;)Ljava/lang/Object; is annotated @inline but could not be inlined:
+ |The operand stack at the callsite in C::t()V contains more values than the
+ |arguments expected by the callee ErrorHandler$::defaultIfIOException(Lscala/Function0;Lscala/Function0;)Ljava/lang/Object;. These values would be discarded
+ |when entering an exception handler declared in the inlined method.""".stripMargin
+
+ compileClasses(compiler)(code, allowMessage = _.msg == msg)
+ }
+
+ @Test
+ def t6547(): Unit = { // "pos" test -- check that it compiles
+ val code =
+ """trait ConfigurableDefault[@specialized V] {
+ | def fillArray(arr: Array[V], v: V) = (arr: Any) match {
+ | case x: Array[Int] => null
+ | case x: Array[Long] => v.asInstanceOf[Long]
+ | }
+ |}
+ """.stripMargin
+ compileClasses(compiler)(code)
+ }
+
+ @Test
+ def t8062(): Unit = {
+ val c1 =
+ """package warmup
+ |object Warmup { def filter[A](p: Any => Boolean): Any = filter[Any](p) }
+ """.stripMargin
+ val c2 = "class C { def t = warmup.Warmup.filter[Any](x => false) }"
+ val List(c, _, _) = compileClassesSeparately(List(c1, c2), extraArgs = OptimizedBytecodeTest.args)
+ assertInvoke(getSingleMethod(c, "t"), "warmup/Warmup$", "filter")
+ }
+
+ @Test
+ def t8306(): Unit = { // "pos" test
+ val code =
+ """class C {
+ | def foo: Int = 123
+ | lazy val extension: Int = foo match {
+ | case idx if idx != -1 => 15
+ | case _ => 17
+ | }
+ |}
+ """.stripMargin
+ compileClasses(compiler)(code)
+ }
+
+ @Test
+ def t8359(): Unit = { // "pos" test
+ // This is a minimization of code that crashed the compiler during bootstrapping
+ // in the first iteration of https://github.com/scala/scala/pull/4373, the PR
+ // that adjusted the order of free and declared params in LambdaLift.
+
+ // Was:
+ // java.lang.AssertionError: assertion failed:
+ // Record Record(<$anon: Function1>,Map(value a$1 -> Deref(LocalVar(value b)))) does not contain a field value b$1
+ // at scala.tools.nsc.Global.assert(Global.scala:262)
+ // at scala.tools.nsc.backend.icode.analysis.CopyPropagation$copyLattice$State.getFieldNonRecordValue(CopyPropagation.scala:113)
+ // at scala.tools.nsc.backend.icode.analysis.CopyPropagation$copyLattice$State.getFieldNonRecordValue(CopyPropagation.scala:122)
+ // at scala.tools.nsc.backend.opt.ClosureElimination$ClosureElim$$anonfun$analyzeMethod$1$$anonfun$apply$2.replaceFieldAccess$1(ClosureElimination.scala:124)
+ val code =
+ """package test
+ |class Typer {
+ | def bar(a: Boolean, b: Boolean): Unit = {
+ | @inline
+ | def baz(): Unit = {
+ | ((_: Any) => (Typer.this, a, b)).apply("")
+ | }
+ | ((_: Any) => baz()).apply("")
+ | }
+ |}
+ """.stripMargin
+ compileClasses(compiler)(code)
+ }
+
+ @Test
+ def t9123(): Unit = { // "pos" test
+ val code =
+ """trait Setting {
+ | type T
+ | def value: T
+ |}
+ |object Test {
+ | def test(x: Some[Setting]) = x match {
+ | case Some(dep) => Some(dep.value) map (_ => true)
+ | }
+ |}
+ """.stripMargin
+ compileClasses(compiler)(code)
+ }
+
+ @Test
+ def traitForceInfo(): Unit = {
+ // This did NOT crash unless it's in the interactive package.
+ // error: java.lang.AssertionError: assertion failed: trait Contexts.NoContext$ linkedModule: <none>List()
+ // at scala.Predef$.assert(Predef.scala:160)
+ // at scala.tools.nsc.symtab.classfile.ClassfileParser$innerClasses$.innerSymbol$1(ClassfileParser.scala:1211)
+ // at scala.tools.nsc.symtab.classfile.ClassfileParser$innerClasses$.classSymbol(ClassfileParser.scala:1223)
+ // at scala.tools.nsc.symtab.classfile.ClassfileParser.classNameToSymbol(ClassfileParser.scala:489)
+ // at scala.tools.nsc.symtab.classfile.ClassfileParser.sig2type$1(ClassfileParser.scala:757)
+ // at scala.tools.nsc.symtab.classfile.ClassfileParser.sig2type$1(ClassfileParser.scala:789)
+ val code =
+ """package scala.tools.nsc
+ |package interactive
+ |
+ |trait MyContextTrees {
+ | val self: Global
+ | val NoContext = self.analyzer.NoContext
+ |}
+ """.stripMargin
+ compileClasses(compiler)(code)
+ }
+
+ @Test
+ def t9160(): Unit = {
+ val code =
+ """class C {
+ | def getInt: Int = 0
+ | def t(trees: Object): Int = {
+ | trees match {
+ | case Some(elems) =>
+ | case tree => getInt
+ | }
+ | 55
+ | }
+ |}
+ """.stripMargin
+ val List(c) = compileClasses(compiler)(code)
+ assertEquals(
+ getSingleMethod(c, "t").instructions.summary,
+ List(
+ ALOAD /*1*/, INSTANCEOF /*Some*/, IFNE /*A*/,
+ ALOAD /*0*/, "getInt", POP,
+ -1 /*A*/, BIPUSH, IRETURN))
+ }
+
+ @Test
+ def t8796(): Unit = {
+ val code =
+ """final class C {
+ | def pr(): Unit = ()
+ | def t(index: Int): Unit = index match {
+ | case 0 => pr()
+ | case 1 => pr()
+ | case _ => t(index - 2)
+ | }
+ |}
+ """.stripMargin
+ val List(c) = compileClasses(compiler)(code)
+ assertEquals(
+ getSingleMethod(c, "t").instructions.summary,
+ List(
+ -1 /*A*/, ILOAD /*1*/, TABLESWITCH,
+ -1, ALOAD, "pr", RETURN,
+ -1, ALOAD, "pr", RETURN,
+ -1, ILOAD, ICONST_2, ISUB, ISTORE, GOTO /*A*/))
+ }
+
+ @Test
+ def t8524(): Unit = {
+ val c1 =
+ """package library
+ |object Library {
+ | @inline def pleaseInlineMe() = 1
+ | object Nested { @inline def pleaseInlineMe() = 2 }
+ |}
+ """.stripMargin
+
+ val c2 =
+ """class C {
+ | def t = library.Library.pleaseInlineMe() + library.Library.Nested.pleaseInlineMe()
+ |}
+ """.stripMargin
+
+ val cls = compileClassesSeparately(List(c1, c2), extraArgs = OptimizedBytecodeTest.args)
+ val c = cls.find(_.name == "C").get
+ assertEquals(
+ getSingleMethod(c, "t").instructions.summary,
+ List(
+ GETSTATIC, IFNONNULL, ACONST_NULL, ATHROW, // module load and null checks not yet eliminated
+ -1, ICONST_1, GETSTATIC, IFNONNULL, ACONST_NULL, ATHROW,
+ -1, ICONST_2, IADD, IRETURN))
+ }
+
+ @Test
+ def privateInline(): Unit = {
+ val code =
+ """final class C {
+ | private var x1 = false
+ | var x2 = false
+ |
+ | @inline private def wrapper1[T](body: => T): T = {
+ | val saved = x1
+ | x1 = true
+ | try body
+ | finally x1 = saved
+ | }
+ |
+ | @inline private def wrapper2[T](body: => T): T = {
+ | val saved = x2
+ | x2 = true
+ | try body
+ | finally x2 = saved
+ | }
+ | // inlined
+ | def f1a() = wrapper1(5)
+ | // not inlined: even after inlining `identity`, the Predef module is already on the stack for the
+ | // subsequent null check (the receiver of an inlined method, in this case Predef, is checked for
+ | // nullness, to ensure an NPE is thrown)
+ | def f1b() = identity(wrapper1(5))
+ |
+ | def f2a() = wrapper2(5) // inlined
+ | def f2b() = identity(wrapper2(5)) // not inlined
+ |}
+ """.stripMargin
+ val List(c) = compileClasses(compiler)(code, allowMessage = _.msg.contains("exception handler declared in the inlined method"))
+ assertInvoke(getSingleMethod(c, "f1a"), "C", "C$$$anonfun$1")
+ assertInvoke(getSingleMethod(c, "f1b"), "C", "wrapper1")
+ assertInvoke(getSingleMethod(c, "f2a"), "C", "C$$$anonfun$3")
+ assertInvoke(getSingleMethod(c, "f2b"), "C", "wrapper2")
+ }
+}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala b/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala
index 342f403426..0d353e930e 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/CodeGenTools.scala
@@ -50,9 +50,11 @@ object CodeGenTools {
}
def newCompilerWithoutVirtualOutdir(defaultArgs: String = "-usejavacp", extraArgs: String = ""): Global = {
- val settings = new Settings()
+ def showError(s: String) = throw new Exception(s)
+ val settings = new Settings(showError)
val args = (CommandLineParser tokenize defaultArgs) ++ (CommandLineParser tokenize extraArgs)
- settings.processArguments(args, processAll = true)
+ val (_, nonSettingsArgs) = settings.processArguments(args, processAll = true)
+ if (nonSettingsArgs.nonEmpty) showError("invalid compiler flags: " + nonSettingsArgs.mkString(" "))
new Global(settings, new StoreReporter)
}
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
index a685ae7dd5..99acb318de 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/SimplifyJumpsTest.scala
@@ -96,10 +96,22 @@ class SimplifyJumpsTest {
instructionsFromMethod(method),
List(VarOp(ILOAD, 1), Jump(IFLT, Label(3))) ::: rest.tail )
- // no label allowed between begin and rest. if there's another label, then there could be a
- // branch that label. eliminating the GOTO would change the behavior.
- val nonOptMethod = genMethod()(begin ::: Label(22) :: rest: _*)
- assertFalse(LocalOptImpls.simplifyJumps(nonOptMethod))
+ // branch over goto is OK even if there's a label in between, if that label is not a jump target
+ val withNonJumpTargetLabel = genMethod()(begin ::: Label(22) :: rest: _*)
+ assertTrue(LocalOptImpls.simplifyJumps(withNonJumpTargetLabel))
+ assertSameCode(
+ instructionsFromMethod(withNonJumpTargetLabel),
+ List(VarOp(ILOAD, 1), Jump(IFLT, Label(3)), Label(22)) ::: rest.tail )
+
+ // if the Label(22) between IFGE and GOTO is the target of some jump, we cannot rewrite the IFGE
+ // and remove the GOTO: removing the GOTO would change semantics. However, the jump that targets
+ // Label(22) will be re-written (jump-chain collapsing), so in a second round, the IFGE is still
+ // rewritten to IFLT
+ val twoRounds = genMethod()(List(VarOp(ILOAD, 1), Jump(IFLE, Label(22))) ::: begin ::: Label(22) :: rest: _*)
+ assertTrue(LocalOptImpls.simplifyJumps(twoRounds))
+ assertSameCode(
+ instructionsFromMethod(twoRounds),
+ List(VarOp(ILOAD, 1), Jump(IFLE, Label(3)), VarOp(ILOAD, 1), Jump(IFLT, Label(3)), Label(22)) ::: rest.tail )
}
@Test
@@ -167,6 +179,9 @@ class SimplifyJumpsTest {
VarOp(ILOAD, 1),
Jump(IFGE, Label(target)),
+ VarOp(ILOAD, 1), // some code to prevent rewriting the conditional jump
+ Op(IRETURN),
+
Label(4),
Jump(GOTO, Label(3)),
diff --git a/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala b/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala
index ec4621b230..3fc3144eb2 100644
--- a/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala
+++ b/test/junit/scala/tools/nsc/transform/patmat/PatmatBytecodeTest.scala
@@ -134,4 +134,29 @@ class PatmatBytecodeTest extends ClearAfterClass {
NEW, DUP, ALOAD /*1*/, "<init>", ATHROW,
/*R*/ -1, ALOAD /*2*/, ARETURN))
}
+
+ @Test
+ def t6941(): Unit = {
+ val code =
+ """class C {
+ | def a(xs: List[Int]) = xs match {
+ | case x :: _ => x
+ | }
+ | def b(xs: List[Int]) = xs match {
+ | case xs: ::[Int] => xs.head
+ | }
+ |}
+ """.stripMargin
+ val c = compileClasses(optCompiler)(code, allowMessage = _.msg.contains("may not be exhaustive")).head
+
+ val expected = List(
+ ALOAD /*1*/ , INSTANCEOF /*::*/ , IFEQ /*A*/ ,
+ ALOAD, CHECKCAST /*::*/ , "head", "unboxToInt",
+ ISTORE, GOTO /*B*/ ,
+ -1 /*A*/ , NEW /*MatchError*/ , DUP, ALOAD /*1*/ , "<init>", ATHROW,
+ -1 /*B*/ , ILOAD, IRETURN)
+
+ assertEquals(textify(findAsmMethod(c, "a")), getSingleMethod(c, "a").instructions.summary, expected)
+ assertEquals(textify(findAsmMethod(c, "b")), getSingleMethod(c, "b").instructions.summary, expected)
+ }
}
diff --git a/test/pending/run/private-inline.check b/test/pending/run/private-inline.check
deleted file mode 100644
index e71aec2fcf..0000000000
--- a/test/pending/run/private-inline.check
+++ /dev/null
@@ -1,13 +0,0 @@
-private-inline.scala:24: warning: Could not inline required method wrapper1 because callee contains exception handlers / finally clause, and is invoked with non-empty operand stack.
- def f1b() = identity(wrapper1(5))
- ^
-private-inline.scala:24: warning: At the end of the day, could not inline @inline-marked method wrapper1
- def f1b() = identity(wrapper1(5))
- ^
-private-inline.scala:29: warning: Could not inline required method wrapper2 because callee contains exception handlers / finally clause, and is invoked with non-empty operand stack.
- def f2b() = identity(wrapper2(5))
- ^
-private-inline.scala:29: warning: At the end of the day, could not inline @inline-marked method wrapper2
- def f2b() = identity(wrapper2(5))
- ^
-20
diff --git a/test/pending/run/private-inline.flags b/test/pending/run/private-inline.flags
deleted file mode 100644
index c550fdce16..0000000000
--- a/test/pending/run/private-inline.flags
+++ /dev/null
@@ -1 +0,0 @@
--optimise -Yinline-warnings -Ybackend:GenASM
diff --git a/test/pending/run/private-inline.scala b/test/pending/run/private-inline.scala
deleted file mode 100644
index 60fef9efca..0000000000
--- a/test/pending/run/private-inline.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-
-final class A {
- private var x1 = false
- var x2 = false
-
- // manipulates private var
- @inline private def wrapper1[T](body: => T): T = {
- val saved = x1
- x1 = true
- try body
- finally x1 = saved
- }
- // manipulates public var
- @inline private def wrapper2[T](body: => T): T = {
- val saved = x2
- x2 = true
- try body
- finally x2 = saved
- }
-
- // not inlined
- def f1a() = wrapper1(5)
- // inlined!
- def f1b() = identity(wrapper1(5))
-
- // not inlined
- def f2a() = wrapper2(5)
- // inlined!
- def f2b() = identity(wrapper2(5))
-}
-
-object Test {
- def methodClasses = List("f1a", "f2a") map ("A$$anonfun$" + _ + "$1")
-
- def main(args: Array[String]): Unit = {
- val a = new A
- import a._
- println(f1a() + f1b() + f2a() + f2b())
-
- // Don't know how else to test this: all these should have been
- // inlined, so all should fail.
- methodClasses foreach { clazz =>
-
- val foundClass = (
- try Class.forName(clazz)
- catch { case _: Throwable => null }
- )
-
- assert(foundClass == null, foundClass)
- }
- }
-}