core: fix 'if' detection
This commit is contained in:
@@ -72,20 +72,20 @@ public class BlockNode extends AttrNode implements IBlock {
|
||||
private static List<BlockNode> cleanSuccessors(BlockNode block) {
|
||||
List<BlockNode> sucList = block.getSuccessors();
|
||||
List<BlockNode> nodes = new ArrayList<BlockNode>(sucList.size());
|
||||
LoopAttr loop = (LoopAttr) block.getAttributes().get(AttributeType.LOOP);
|
||||
if (loop == null) {
|
||||
if (block.getAttributes().contains(AttributeFlag.LOOP_END)) {
|
||||
LoopAttr loop = (LoopAttr) block.getAttributes().get(AttributeType.LOOP);
|
||||
for (BlockNode b : sucList) {
|
||||
if (!b.getAttributes().contains(AttributeType.EXC_HANDLER)) {
|
||||
// don't follow back edge
|
||||
if (loop.getStart() == b) {
|
||||
continue;
|
||||
}
|
||||
nodes.add(b);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (BlockNode b : sucList) {
|
||||
if (!b.getAttributes().contains(AttributeType.EXC_HANDLER)) {
|
||||
// don't follow back edge
|
||||
if (loop.getStart() == b && loop.getEnd() == block) {
|
||||
continue;
|
||||
}
|
||||
nodes.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -458,12 +458,14 @@ public class BlockMakerVisitor extends AbstractVisitor {
|
||||
if (exitBlock != otherExitBlock
|
||||
&& otherExitBlock.isDominator(pred)
|
||||
&& otherExitBlock.getPredecessors().size() == 1) {
|
||||
// merge
|
||||
BlockNode otherPred = otherExitBlock.getPredecessors().get(0);
|
||||
removeConnection(otherPred, otherExitBlock);
|
||||
connect(otherPred, exitBlock);
|
||||
cleanExitNodes(mth);
|
||||
return true;
|
||||
if (pred != otherPred) {
|
||||
// merge
|
||||
removeConnection(otherPred, otherExitBlock);
|
||||
connect(otherPred, exitBlock);
|
||||
cleanExitNodes(mth);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,8 +201,7 @@ public class RegionMaker {
|
||||
}
|
||||
|
||||
List<BlockNode> merged = new ArrayList<BlockNode>(2);
|
||||
IfInfo mergedIf = mergeNestedIfNodes(condBlock,
|
||||
ifnode.getThenBlock(), ifnode.getElseBlock(), merged);
|
||||
IfInfo mergedIf = mergeNestedIfNodes(condBlock, ifnode, merged);
|
||||
if (mergedIf != null) {
|
||||
condBlock = mergedIf.getIfnode();
|
||||
if (!loop.getLoopBlocks().contains(mergedIf.getThenBlock())) {
|
||||
@@ -398,54 +397,56 @@ public class RegionMaker {
|
||||
}
|
||||
|
||||
private BlockNode processIf(IRegion currentRegion, BlockNode block, IfNode ifnode, RegionStack stack) {
|
||||
BlockNode bThen = ifnode.getThenBlock();
|
||||
BlockNode bElse = ifnode.getElseBlock();
|
||||
|
||||
if (block.getAttributes().contains(AttributeFlag.SKIP)) {
|
||||
// block already included in other if region
|
||||
return bThen;
|
||||
// block already included in other 'if' region
|
||||
return ifnode.getThenBlock();
|
||||
}
|
||||
|
||||
final BlockNode thenBlock;
|
||||
final BlockNode elseBlock;
|
||||
BlockNode out = null;
|
||||
BlockNode thenBlock = null;
|
||||
BlockNode elseBlock = null;
|
||||
|
||||
IfRegion ifRegion = new IfRegion(currentRegion, block);
|
||||
currentRegion.getSubBlocks().add(ifRegion);
|
||||
|
||||
IfInfo mergedIf = mergeNestedIfNodes(block, bThen, bElse, null);
|
||||
IfInfo mergedIf = mergeNestedIfNodes(block, ifnode, null);
|
||||
if (mergedIf != null) {
|
||||
ifRegion.setCondition(mergedIf.getCondition());
|
||||
thenBlock = mergedIf.getThenBlock();
|
||||
elseBlock = mergedIf.getElseBlock();
|
||||
out = BlockUtils.getPathCrossBlockFor(mth, thenBlock, elseBlock);
|
||||
} else {
|
||||
for (BlockNode d : block.getDominatesOn()) {
|
||||
if (d != bThen && d != bElse) {
|
||||
out = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// invert condition (compiler often do it)
|
||||
ifnode.invertCondition();
|
||||
bThen = ifnode.getThenBlock();
|
||||
bElse = ifnode.getElseBlock();
|
||||
final BlockNode bThen = ifnode.getThenBlock();
|
||||
final BlockNode bElse = ifnode.getElseBlock();
|
||||
|
||||
thenBlock = bThen;
|
||||
// select else and exit blocks
|
||||
if (block.getDominatesOn().size() == 2
|
||||
&& !BlockUtils.isPathExists(bThen, bElse)) {
|
||||
// select 'then', 'else' and 'exit' blocks
|
||||
if (bElse.getPredecessors().size() != 1
|
||||
&& BlockUtils.isPathExists(bThen, bElse)) {
|
||||
thenBlock = bThen;
|
||||
elseBlock = null;
|
||||
out = bElse;
|
||||
} else if (bThen.getPredecessors().size() != 1
|
||||
&& BlockUtils.isPathExists(bElse, bThen)) {
|
||||
ifnode.invertCondition();
|
||||
thenBlock = ifnode.getThenBlock();
|
||||
elseBlock = null;
|
||||
out = ifnode.getElseBlock();
|
||||
} else if (block.getDominatesOn().size() == 2) {
|
||||
thenBlock = bThen;
|
||||
elseBlock = bElse;
|
||||
out = BlockUtils.getPathCrossBlockFor(mth, bThen, bElse);
|
||||
} else if (bElse.getPredecessors().size() != 1) {
|
||||
thenBlock = bThen;
|
||||
elseBlock = null;
|
||||
out = bElse;
|
||||
} else {
|
||||
if (bElse.getPredecessors().size() != 1) {
|
||||
out = bElse;
|
||||
} else {
|
||||
elseBlock = bElse;
|
||||
for (BlockNode d : block.getDominatesOn()) {
|
||||
if (d != bThen && d != bElse) {
|
||||
out = d;
|
||||
break;
|
||||
}
|
||||
thenBlock = bThen;
|
||||
elseBlock = bElse;
|
||||
for (BlockNode d : block.getDominatesOn()) {
|
||||
if (d != bThen && d != bElse) {
|
||||
out = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -454,26 +455,26 @@ public class RegionMaker {
|
||||
}
|
||||
}
|
||||
|
||||
if (elseBlock != null && stack.containsExit(elseBlock)) {
|
||||
elseBlock = null;
|
||||
}
|
||||
|
||||
stack.push(ifRegion);
|
||||
stack.addExit(out);
|
||||
|
||||
ifRegion.setThenRegion(makeRegion(thenBlock, stack));
|
||||
ifRegion.setElseRegion(elseBlock == null ? null : makeRegion(elseBlock, stack));
|
||||
if (elseBlock == null || stack.containsExit(elseBlock)) {
|
||||
ifRegion.setElseRegion(null);
|
||||
} else {
|
||||
ifRegion.setElseRegion(makeRegion(elseBlock, stack));
|
||||
}
|
||||
|
||||
stack.pop();
|
||||
return out;
|
||||
}
|
||||
|
||||
private IfInfo mergeNestedIfNodes(BlockNode block, BlockNode bThen, BlockNode bElse, List<BlockNode> merged) {
|
||||
private IfInfo mergeNestedIfNodes(BlockNode block, IfNode ifnode, List<BlockNode> merged) {
|
||||
IfInfo info = new IfInfo();
|
||||
info.setIfnode(block);
|
||||
info.setCondition(IfCondition.fromIfBlock(block));
|
||||
info.setThenBlock(bThen);
|
||||
info.setElseBlock(bElse);
|
||||
info.setThenBlock(ifnode.getThenBlock());
|
||||
info.setElseBlock(ifnode.getElseBlock());
|
||||
return mergeNestedIfNodes(info, merged);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@ package jadx.tests.internal.conditions;
|
||||
import jadx.api.InternalJadxTest;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestTernary2 extends InternalJadxTest {
|
||||
@@ -20,12 +21,15 @@ public class TestTernary2 extends InternalJadxTest {
|
||||
}
|
||||
}
|
||||
|
||||
//@Test
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
System.out.println(code);
|
||||
|
||||
assertThat(code, containsString("assertTrue(f(1, 0) == 0);"));
|
||||
assertEquals(1, count(code, "assertTrue"));
|
||||
assertEquals(1, count(code, "f(1, 0)"));
|
||||
// TODO:
|
||||
// assertThat(code, containsString("assertTrue(f(1, 0) == 0);"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user