未验证 提交 f37c23db 编写于 作者: S Skylot

fix: use correct top block for try blocks with same start (#1304)

上级 d2bde0be
......@@ -323,23 +323,14 @@ public class BlockExceptionHandler {
private static boolean wrapBlocksWithTryCatch(MethodNode mth, TryCatchBlockAttr tryCatchBlock) {
List<BlockNode> blocks = tryCatchBlock.getBlocks();
BlockNode top = searchTopBlock(mth, blocks);
if (top.getPredecessors().isEmpty()) {
if (top.getPredecessors().isEmpty() && top != mth.getEnterBlock()) {
return false;
}
BlockNode bottom = searchBottomBlock(mth, blocks);
if (Consts.DEBUG_EXC_HANDLERS) {
LOG.debug("TryCatch #{} split: top {}, bottom: {}", tryCatchBlock.id(), top, bottom);
}
BlockNode topSplitterBlock;
if (top == mth.getEnterBlock()) {
BlockNode fixedTop = mth.getEnterBlock().getSuccessors().get(0);
topSplitterBlock = BlockSplitter.blockSplitTop(mth, fixedTop);
} else {
BlockNode existTopSplitter = BlockUtils.getBlockWithFlag(top.getPredecessors(), AFlag.EXC_TOP_SPLITTER);
topSplitterBlock = existTopSplitter != null ? existTopSplitter : BlockSplitter.blockSplitTop(mth, top);
}
BlockNode topSplitterBlock = getTopSplitterBlock(mth, top);
topSplitterBlock.add(AFlag.EXC_TOP_SPLITTER);
topSplitterBlock.add(AFlag.SYNTHETIC);
......@@ -356,6 +347,10 @@ public class BlockExceptionHandler {
BlockSplitter.connect(bottom, bottomSplitterBlock);
}
if (Consts.DEBUG_EXC_HANDLERS) {
LOG.debug("TryCatch #{} result splitters: top {}, bottom: {}",
tryCatchBlock.id(), topSplitterBlock, bottomSplitterBlock);
}
connectSplittersAndHandlers(tryCatchBlock, topSplitterBlock, bottomSplitterBlock);
for (BlockNode block : blocks) {
......@@ -373,6 +368,25 @@ public class BlockExceptionHandler {
return true;
}
private static BlockNode getTopSplitterBlock(MethodNode mth, BlockNode top) {
if (top == mth.getEnterBlock()) {
BlockNode fixedTop = mth.getEnterBlock().getSuccessors().get(0);
return BlockSplitter.blockSplitTop(mth, fixedTop);
}
BlockNode existPredTopSplitter = BlockUtils.getBlockWithFlag(top.getPredecessors(), AFlag.EXC_TOP_SPLITTER);
if (existPredTopSplitter != null) {
return existPredTopSplitter;
}
// try to reuse exists splitter on empty simple path below top block
if (top.getCleanSuccessors().size() == 1 && top.getInstructions().isEmpty()) {
BlockNode otherTopSplitter = BlockUtils.getBlockWithFlag(top.getCleanSuccessors(), AFlag.EXC_TOP_SPLITTER);
if (otherTopSplitter != null && otherTopSplitter.getPredecessors().size() == 1) {
return otherTopSplitter;
}
}
return BlockSplitter.blockSplitTop(mth, top);
}
private static BlockNode searchTopBlock(MethodNode mth, List<BlockNode> blocks) {
BlockNode top = BlockUtils.getTopBlock(blocks);
if (top != null) {
......
......@@ -572,9 +572,9 @@ public class BlockUtils {
return traverseSuccessorsUntil(start, end, new BitSet(), false);
}
public static BlockNode getTopBlock(Collection<BlockNode> blocks) {
public static BlockNode getTopBlock(List<BlockNode> blocks) {
if (blocks.size() == 1) {
return blocks.iterator().next();
return blocks.get(0);
}
for (BlockNode from : blocks) {
boolean top = true;
......@@ -594,9 +594,9 @@ public class BlockUtils {
/**
* Search last block in control flow graph from input set.
*/
public static BlockNode getBottomBlock(Collection<BlockNode> blocks) {
public static BlockNode getBottomBlock(List<BlockNode> blocks) {
if (blocks.size() == 1) {
return blocks.iterator().next();
return blocks.get(0);
}
for (BlockNode bottomCandidate : blocks) {
boolean bottom = true;
......
......@@ -59,6 +59,10 @@ public class DebugUtils {
}
}
public static void dumpRawTest(MethodNode mth, String desc) {
dumpRaw(mth, desc, method -> method.getName().equals("test"));
}
public static void dumpRaw(MethodNode mth, String desc) {
File out = new File("test-graph-" + desc + "-tmp");
DotGraphVisitor.dumpRaw().save(out, mth);
......
package jadx.tests.integration.trycatch;
import jadx.tests.api.IntegrationTest;
import jadx.tests.api.extensions.inputs.InputPlugin;
import jadx.tests.api.extensions.inputs.TestWithInputPlugins;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestTryCatchFinally13 extends IntegrationTest {
public static class TestCls {
public void test(int i) {
try {
doSomething1();
if (i == -12) {
return;
}
if (i > 10) {
doSomething2();
} else if (i == -1) {
doSomething3();
}
} catch (Exception ex) {
logError();
} finally {
doSomething4();
}
}
private void logError() {
}
private void doSomething1() {
}
private void doSomething2() {
}
private void doSomething3() {
}
private void doSomething4() {
}
}
@TestWithInputPlugins({ InputPlugin.DEX, InputPlugin.JAVA })
public void test() {
assertThat(getClassNode(TestCls.class))
.code()
.containsOne("} finally {");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册