Skip to content

Commit

Permalink
SI-6157 don't inline callee with exception-handler(s) if potentially …
Browse files Browse the repository at this point in the history
…unsafe
  • Loading branch information
magarciaEPFL committed Aug 6, 2012
1 parent 61cc8ff commit 1703736
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 4 deletions.
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
Expand Up @@ -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 }
Expand Down
1 change: 1 addition & 0 deletions test/files/pos/t6157.flags
@@ -0,0 +1 @@
-optimize
25 changes: 25 additions & 0 deletions 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
}
}
}

2 changes: 1 addition & 1 deletion test/files/run/private-inline.scala
Expand Up @@ -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
Expand Down

0 comments on commit 1703736

Please sign in to comment.