fix: resolve some cases of switch in loop (#876)
This commit is contained in:
@@ -119,14 +119,23 @@ public class SwitchNode extends TargetInsnNode {
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(super.toString());
|
||||
for (int i = 0; i < targets.length; i++) {
|
||||
sb.append(CodeWriter.NL);
|
||||
sb.append(" case ").append(keys[i]);
|
||||
sb.append(": goto ").append(InsnUtils.formatOffset(targets[i]));
|
||||
}
|
||||
if (def != -1) {
|
||||
sb.append(CodeWriter.NL);
|
||||
sb.append(" default: goto ").append(InsnUtils.formatOffset(def));
|
||||
if (targetBlocks == null) {
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
sb.append(CodeWriter.NL);
|
||||
sb.append(" case ").append(keys[i]).append(": goto ").append(InsnUtils.formatOffset(targets[i]));
|
||||
}
|
||||
if (def != -1) {
|
||||
sb.append(CodeWriter.NL);
|
||||
sb.append(" default: goto ").append(InsnUtils.formatOffset(def));
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
sb.append(CodeWriter.NL);
|
||||
sb.append(" case ").append(keys[i]).append(": goto ").append(targetBlocks[i]);
|
||||
}
|
||||
if (def != -1) {
|
||||
sb.append(CodeWriter.NL).append(" default: goto ").append(defTargetBlock);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -761,14 +761,30 @@ public class RegionMaker {
|
||||
out = calcPostDomOut(mth, block, mth.getExitBlocks());
|
||||
} else {
|
||||
BlockNode loopEnd = loop.getEnd();
|
||||
// treat 'continue' as exit
|
||||
out = calcPostDomOut(mth, block, loopEnd.getPredecessors());
|
||||
if (out != null) {
|
||||
insertContinueInSwitch(block, out, loopEnd);
|
||||
stack.addExit(loop.getStart());
|
||||
if (stack.containsExit(block)
|
||||
|| block == loopEnd
|
||||
|| loopEnd.getPredecessors().contains(block)) {
|
||||
// in exits or last insn in loop => no 'out' block
|
||||
out = null;
|
||||
} else {
|
||||
// no 'continue'
|
||||
out = calcPostDomOut(mth, block, Collections.singletonList(loopEnd));
|
||||
// treat 'continue' as exit
|
||||
out = calcPostDomOut(mth, block, loopEnd.getPredecessors());
|
||||
if (out != null) {
|
||||
insertContinueInSwitch(block, out, loopEnd);
|
||||
} else {
|
||||
// no 'continue'
|
||||
out = calcPostDomOut(mth, block, Collections.singletonList(loopEnd));
|
||||
}
|
||||
}
|
||||
if (out == loop.getStart()) {
|
||||
// no other outs instead back edge to loop start
|
||||
out = null;
|
||||
}
|
||||
}
|
||||
if (out != null && processedBlocks.get(out.getId())) {
|
||||
// out block already processed, prevent endless loop
|
||||
throw new JadxRuntimeException("Failed to find switch 'out' block");
|
||||
}
|
||||
|
||||
SwitchRegion sw = new SwitchRegion(currentRegion, block);
|
||||
|
||||
@@ -21,6 +21,7 @@ import jadx.core.utils.exceptions.JadxOverflowException;
|
||||
|
||||
public class ErrorsCounter {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ErrorsCounter.class);
|
||||
private static final boolean PRINT_MTH_SIZE = true;
|
||||
|
||||
private final Set<IAttributeNode> errorNodes = new HashSet<>();
|
||||
private int errorsCount;
|
||||
@@ -40,6 +41,10 @@ public class ErrorsCounter {
|
||||
errorsCount++;
|
||||
|
||||
String msg = formatMsg(node, error);
|
||||
if (PRINT_MTH_SIZE && node instanceof MethodNode) {
|
||||
long insnsCount = ((MethodNode) node).countInsns();
|
||||
msg = "[" + insnsCount + "] " + msg;
|
||||
}
|
||||
if (e == null) {
|
||||
LOG.error(msg);
|
||||
} else if (e instanceof JadxOverflowException) {
|
||||
|
||||
Reference in New Issue
Block a user