summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/symtab
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2014-06-04 19:01:49 +0200
committerLukas Rytz <lukas.rytz@gmail.com>2014-06-04 19:03:23 +0200
commit62648206f04da064f3f490c412abeca195255bf7 (patch)
tree895f424c94e773fea0a2e2022b5eefb25007e494 /src/compiler/scala/tools/nsc/symtab
parente10ea0ca1d8dcf97e7bfcfed5b3a0a283381525e (diff)
downloadscala-62648206f04da064f3f490c412abeca195255bf7.tar.gz
scala-62648206f04da064f3f490c412abeca195255bf7.tar.bz2
scala-62648206f04da064f3f490c412abeca195255bf7.zip
Don't crash on dead code in ICodeReader
Diffstat (limited to 'src/compiler/scala/tools/nsc/symtab')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala48
1 files changed, 28 insertions, 20 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 6ca2205881..149b4fe446 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -780,32 +780,40 @@ abstract class ICodeReader extends ClassfileParser {
bb = otherBlock
// Console.println("\t> entering bb: " + bb)
}
- instr match {
- case LJUMP(target) =>
- otherBlock = blocks(target)
- bb.emitOnly(JUMP(otherBlock))
- case LCJUMP(success, failure, cond, kind) =>
- otherBlock = blocks(success)
- val failBlock = blocks(failure)
- bb.emitOnly(CJUMP(otherBlock, failBlock, cond, kind))
+ if (bb.closed) {
+ // the basic block is closed, i.e. the previous instruction was a jump, return or throw,
+ // but the next instruction is not a jump target. this means that the next instruction is
+ // dead code. we can therefore advance until the next jump target.
+ debuglog(s"ICode reader skipping dead instruction $instr in classfile $instanceCode")
+ } else {
+ instr match {
+ case LJUMP(target) =>
+ otherBlock = blocks(target)
+ bb.emitOnly(JUMP(otherBlock))
+
+ case LCJUMP(success, failure, cond, kind) =>
+ otherBlock = blocks(success)
+ val failBlock = blocks(failure)
+ bb.emitOnly(CJUMP(otherBlock, failBlock, cond, kind))
- case LCZJUMP(success, failure, cond, kind) =>
- otherBlock = blocks(success)
- val failBlock = blocks(failure)
- bb.emitOnly(CZJUMP(otherBlock, failBlock, cond, kind))
+ case LCZJUMP(success, failure, cond, kind) =>
+ otherBlock = blocks(success)
+ val failBlock = blocks(failure)
+ bb.emitOnly(CZJUMP(otherBlock, failBlock, cond, kind))
- case LSWITCH(tags, targets) =>
- bb.emitOnly(SWITCH(tags, targets map blocks))
+ case LSWITCH(tags, targets) =>
+ bb.emitOnly(SWITCH(tags, targets map blocks))
- case RETURN(_) =>
- bb emitOnly instr
+ case RETURN(_) =>
+ bb emitOnly instr
- case THROW(clasz) =>
- bb emitOnly instr
+ case THROW(clasz) =>
+ bb emitOnly instr
- case _ =>
- bb emit instr
+ case _ =>
+ bb emit instr
+ }
}
}