diff options
author | Lukas Rytz <lukas.rytz@gmail.com> | 2014-06-04 19:01:49 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@gmail.com> | 2014-06-04 19:03:23 +0200 |
commit | 62648206f04da064f3f490c412abeca195255bf7 (patch) | |
tree | 895f424c94e773fea0a2e2022b5eefb25007e494 /src/compiler | |
parent | e10ea0ca1d8dcf97e7bfcfed5b3a0a283381525e (diff) | |
download | scala-62648206f04da064f3f490c412abeca195255bf7.tar.gz scala-62648206f04da064f3f490c412abeca195255bf7.tar.bz2 scala-62648206f04da064f3f490c412abeca195255bf7.zip |
Don't crash on dead code in ICodeReader
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala | 48 |
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 + } } } |