From 62648206f04da064f3f490c412abeca195255bf7 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 4 Jun 2014 19:01:49 +0200 Subject: Don't crash on dead code in ICodeReader --- .../tools/nsc/symtab/classfile/ICodeReader.scala | 48 +++++++++++++--------- 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'src') 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 + } } } -- cgit v1.2.3