diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-06-07 14:45:33 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-06-07 15:08:41 +1000 |
commit | 9b6a65bc890081b48a86e72aa3eb49aaf2d69d09 (patch) | |
tree | a43899a0c75f366e0998b25f9dc5d663d4d2156a | |
parent | 650fbee7855c7162bf3cf23cb8340704274834d9 (diff) | |
download | scala-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.scala | 4 | ||||
-rw-r--r-- | test/files/run/t9806.scala | 18 |
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)) + } + } +} |