summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Garcia <miguelalfredo.garcia@epfl.ch>2012-08-06 18:31:35 +0200
committerMiguel Garcia <miguelalfredo.garcia@epfl.ch>2012-08-06 18:31:35 +0200
commit17037367049312eb3d26766a5759295ac9f8aed6 (patch)
tree0418da6136eb25aefd87fb6e4f685877d99ddd41
parent61cc8ff61c81a1276a921ad5288ee3bebea1c96e (diff)
downloadscala-17037367049312eb3d26766a5759295ac9f8aed6.tar.gz
scala-17037367049312eb3d26766a5759295ac9f8aed6.tar.bz2
scala-17037367049312eb3d26766a5759295ac9f8aed6.zip
SI-6157 don't inline callee with exception-handler(s) if potentially unsafe
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala4
-rw-r--r--test/files/pos/t6157.flags1
-rw-r--r--test/files/pos/t6157.scala25
-rw-r--r--test/files/run/private-inline.scala2
5 files changed, 36 insertions, 4 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
index 962c47f443..e791936470 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
@@ -736,7 +736,13 @@ abstract class TypeFlowAnalysis {
val succs = point.successors filter relevantBBs
succs foreach { p =>
assert((p.predecessors filter isOnPerimeter).isEmpty)
- val updated = lattice.lub(List(output, in(p)), p.exceptionHandlerStart)
+ val existing = in(p)
+ // TODO move the following assertion to typeFlowLattice.lub2 for wider applicability (ie MethodTFA in addition to MTFAGrowable).
+ assert(existing == lattice.bottom ||
+ p.exceptionHandlerStart ||
+ (output.stack.length == existing.stack.length),
+ "Trying to merge non-bottom type-stacks with different stack heights. For a possible cause see SI-6157.")
+ val updated = lattice.lub(List(output, existing), p.exceptionHandlerStart)
if(updated != in(p)) {
in(p) = updated
enqueue(p)
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index dd7676a371..22f0a9ca7c 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -981,8 +981,8 @@ abstract class Inliners extends SubComponent {
return DontInlineHere("too low score (heuristics)")
}
- if(inc.hasHandlers && (stackLength != 0)) {
- // TODO pending return DontInlineHere("callee contains exception handlers / finally clause, and is invoked with non-empty operand stack") // SI-6157
+ if(inc.hasHandlers && (stackLength > inc.minimumStack)) {
+ return DontInlineHere("callee contains exception handlers / finally clause, and is invoked with non-empty operand stack") // SI-6157
}
if(isKnownToInlineSafely) { return InlineableAtThisCaller }
diff --git a/test/files/pos/t6157.flags b/test/files/pos/t6157.flags
new file mode 100644
index 0000000000..0ebca3e7af
--- /dev/null
+++ b/test/files/pos/t6157.flags
@@ -0,0 +1 @@
+ -optimize
diff --git a/test/files/pos/t6157.scala b/test/files/pos/t6157.scala
new file mode 100644
index 0000000000..7463989b14
--- /dev/null
+++ b/test/files/pos/t6157.scala
@@ -0,0 +1,25 @@
+// 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/run/private-inline.scala b/test/files/run/private-inline.scala
index a45300b026..a62007779c 100644
--- a/test/files/run/private-inline.scala
+++ b/test/files/run/private-inline.scala
@@ -30,7 +30,7 @@ final class A {
}
object Test {
- def methodClasses = List("f1a", "f1b", "f2a", "f2b") map ("A$$anonfun$" + _ + "$1")
+ def methodClasses = List("f1a", "f2a") map ("A$$anonfun$" + _ + "$1")
def main(args: Array[String]): Unit = {
val a = new A