summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-06-07 14:45:33 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-06-07 15:08:41 +1000
commit9b6a65bc890081b48a86e72aa3eb49aaf2d69d09 (patch)
treea43899a0c75f366e0998b25f9dc5d663d4d2156a
parent650fbee7855c7162bf3cf23cb8340704274834d9 (diff)
downloadscala-9b6a65bc890081b48a86e72aa3eb49aaf2d69d09.tar.gz
scala-9b6a65bc890081b48a86e72aa3eb49aaf2d69d09.tar.bz2
scala-9b6a65bc890081b48a86e72aa3eb49aaf2d69d09.zip
SI-9806 Fix incorrect codegen with optimizer, constants, try/catch
The constant optimizer phase performs abstract interpretation of the icode representation of the progam in order to eliminate dead code. For each basic block, the possible and impossible states of each local variable is computed for both a normal and an exceptional exit. A bug in this code incorrectly tracked state for exception exits. This appears to have been an oversight: the new state was computed at each instruction, but it was discarded rather than folded through the intepreter.
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala4
-rw-r--r--test/files/run/t9806.scala18
2 files changed, 20 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala b/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala
index a7ce7dfa04..eafaf41932 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ConstantOptimization.scala
@@ -539,14 +539,14 @@ abstract class ConstantOptimization extends SubComponent {
// number of instructions excluding the last one
val normalCount = block.size - 1
- val exceptionState = in.cleanStack
+ var exceptionState = in.cleanStack
var normalExitState = in
var idx = 0
while (idx < normalCount) {
val inst = block(idx)
normalExitState = interpretInst(normalExitState, inst)
if (normalExitState.locals ne exceptionState.locals)
- exceptionState.copy(locals = exceptionState mergeLocals normalExitState.locals)
+ exceptionState = exceptionState.copy(locals = exceptionState mergeLocals normalExitState.locals)
idx += 1
}
diff --git a/test/files/run/t9806.scala b/test/files/run/t9806.scala
new file mode 100644
index 0000000000..ccde989efe
--- /dev/null
+++ b/test/files/run/t9806.scala
@@ -0,0 +1,18 @@
+object Ex extends Exception
+object Test {
+ def main(args: Array[String]) {
+ try foo catch { case Ex => }
+ }
+
+ def isTrue(b: Boolean) = b
+ def foo = {
+ var streamErrors1 = true
+ try {
+ streamErrors1 = false
+ throw Ex
+ } catch {
+ case ex if streamErrors1 =>
+ assert(isTrue(streamErrors1))
+ }
+ }
+}