fix: additional checks for default switch case exit (#2351)
This commit is contained in:
@@ -58,7 +58,7 @@ final class SwitchRegionMaker {
|
||||
currentRegion.getSubBlocks().add(sw);
|
||||
stack.push(sw);
|
||||
|
||||
BlockNode out = calcSwitchOut(block, stack);
|
||||
BlockNode out = calcSwitchOut(block, insn, stack);
|
||||
stack.addExit(out);
|
||||
|
||||
processFallThroughCases(sw, out, stack, blocksMap);
|
||||
@@ -122,7 +122,7 @@ final class SwitchRegionMaker {
|
||||
return BlockUtils.bitSetToOneBlock(mth, caseExits);
|
||||
}
|
||||
|
||||
private @Nullable BlockNode calcSwitchOut(BlockNode block, RegionStack stack) {
|
||||
private @Nullable BlockNode calcSwitchOut(BlockNode block, SwitchInsn insn, RegionStack stack) {
|
||||
// union of case blocks dominance frontier
|
||||
// works if no fallthrough cases and no returns inside switch
|
||||
BitSet outs = BlockUtils.newBlocksBitSet(mth);
|
||||
@@ -184,11 +184,9 @@ final class SwitchRegionMaker {
|
||||
// check if all returns are equals and should be treated as single out block
|
||||
return allSameReturns(stack);
|
||||
}
|
||||
if (out != imPostDom && !mth.isPreExitBlock(imPostDom)) {
|
||||
// stop other paths at common exit
|
||||
stack.addExit(imPostDom);
|
||||
}
|
||||
if (block.getCleanSuccessors().contains(imPostDom)) {
|
||||
if (imPostDom == insn.getDefTargetBlock()
|
||||
&& block.getCleanSuccessors().contains(imPostDom)
|
||||
&& block.getDomFrontier().get(imPostDom.getId())) {
|
||||
// add exit to stop on empty 'default' block
|
||||
stack.addExit(imPostDom);
|
||||
}
|
||||
@@ -343,5 +341,4 @@ final class SwitchRegionMaker {
|
||||
}
|
||||
return inserted;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -513,7 +513,7 @@ public abstract class IntegrationTest extends TestUtils {
|
||||
}
|
||||
|
||||
private void saveToJar(List<File> files, Path baseDir) throws IOException {
|
||||
Path jarFile = Files.createTempFile(testDir, "tests-" + getTestName() + '-', ".jar");
|
||||
Path jarFile = Files.createTempFile("tests-" + getTestName() + '-', ".jar");
|
||||
try (JarOutputStream jar = new JarOutputStream(Files.newOutputStream(jarFile))) {
|
||||
for (File file : files) {
|
||||
Path fullPath = file.toPath();
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package jadx.tests.integration.switches;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestSwitchInLoop5 extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
private static int test(int r) {
|
||||
int i;
|
||||
while (true) {
|
||||
switch (r) {
|
||||
case 42:
|
||||
i = 32;
|
||||
break;
|
||||
case 52:
|
||||
i = 42;
|
||||
break;
|
||||
default:
|
||||
System.out.println("Default switch case");
|
||||
return 1;
|
||||
}
|
||||
r = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertThat(getClassNode(TestCls.class))
|
||||
.code()
|
||||
.containsOne("default:")
|
||||
.containsOne("System.out.println(");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user