fix: remove move instructions with unused result (#835)
This commit is contained in:
@@ -86,6 +86,7 @@ public class ModVisitor extends AbstractVisitor {
|
||||
InsnRemover remover = new InsnRemover(mth);
|
||||
replaceStep(mth, remover);
|
||||
removeStep(mth, remover);
|
||||
iterativeRemoveStep(mth);
|
||||
}
|
||||
|
||||
private static void replaceStep(MethodNode mth, InsnRemover remover) {
|
||||
@@ -293,6 +294,9 @@ public class ModVisitor extends AbstractVisitor {
|
||||
break;
|
||||
|
||||
default:
|
||||
if (insn.contains(AFlag.REMOVE)) {
|
||||
remover.addAndUnbind(insn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -300,6 +304,33 @@ public class ModVisitor extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static void iterativeRemoveStep(MethodNode mth) {
|
||||
boolean changed;
|
||||
do {
|
||||
changed = false;
|
||||
for (BlockNode block : mth.getBasicBlocks()) {
|
||||
for (InsnNode insn : block.getInstructions()) {
|
||||
if (insn.getType() == InsnType.MOVE
|
||||
&& insn.isAttrStorageEmpty()
|
||||
&& isResultArgNotUsed(insn)) {
|
||||
InsnRemover.remove(mth, block, insn);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (changed);
|
||||
}
|
||||
|
||||
private static boolean isResultArgNotUsed(InsnNode insn) {
|
||||
RegisterArg result = insn.getResult();
|
||||
if (result != null) {
|
||||
SSAVar ssaVar = result.getSVar();
|
||||
return ssaVar.getUseCount() == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void processAnonymousConstructor(MethodNode mth, ConstructorInsn co) {
|
||||
MethodInfo callMth = co.getCallMth();
|
||||
MethodNode callMthNode = mth.dex().resolveMethod(callMth);
|
||||
|
||||
@@ -422,6 +422,7 @@ public class SSATransform extends AbstractVisitor {
|
||||
if (resArg.getRegNum() != arg.getRegNum()
|
||||
&& !resArg.getSVar().isUsedInPhi()) {
|
||||
markThisArgs(resArg);
|
||||
parentInsn.add(AFlag.REMOVE);
|
||||
parentInsn.add(AFlag.DONT_GENERATE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package jadx.tests.integration.others;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestInsnsBeforeSuper2 extends SmaliTest {
|
||||
// @formatter:off
|
||||
/*
|
||||
public class TestInsnsBeforeSuper2 extends java.lang.Exception {
|
||||
private int mErrorType;
|
||||
|
||||
public TestInsnsBeforeSuper2(java.lang.String r9, int r10) {
|
||||
r8 = this;
|
||||
r0 = r8
|
||||
r1 = r9
|
||||
r2 = r10
|
||||
r3 = r0
|
||||
r4 = r1
|
||||
r5 = r2
|
||||
r6 = r1
|
||||
r0.<init>(r6)
|
||||
r7 = 0
|
||||
r0.mErrorType = r7
|
||||
r0.mErrorType = r2
|
||||
return
|
||||
}
|
||||
}
|
||||
*/
|
||||
// @formatter:on
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertThat(getClassNodeFromSmali())
|
||||
.code()
|
||||
.containsOne("super(message);")
|
||||
.containsOne("this.mErrorType = errorType;");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
.class public Lothers/TestInsnsBeforeSuper2;
|
||||
.super Ljava/lang/Exception;
|
||||
.source "MyException.java"
|
||||
|
||||
# instance fields
|
||||
.field private mErrorType:I
|
||||
|
||||
|
||||
# direct methods
|
||||
.method public constructor <init>(Ljava/lang/String;I)V
|
||||
.locals 8
|
||||
|
||||
.prologue
|
||||
move-object v0, p0
|
||||
|
||||
.local v0, "this":Lothers/TestInsnsBeforeSuper2;
|
||||
move-object v1, p1
|
||||
|
||||
.local v1, "message":Ljava/lang/String;
|
||||
move v2, p2
|
||||
|
||||
.line 39
|
||||
.local v2, "errorType":I
|
||||
move-object v3, v0
|
||||
|
||||
.local v3, "this":Lothers/TestInsnsBeforeSuper2;
|
||||
move-object v4, v1
|
||||
|
||||
.local v4, "message":Ljava/lang/String;
|
||||
move v5, v2
|
||||
|
||||
.line 51
|
||||
.end local v0 # "this":Lothers/TestInsnsBeforeSuper2;
|
||||
.end local v1 # "message":Ljava/lang/String;
|
||||
.end local v2 # "errorType":I
|
||||
.local v5, "errorType":I
|
||||
move-object v6, v1
|
||||
|
||||
invoke-direct {v0, v6}, Ljava/lang/Exception;-><init>(Ljava/lang/String;)V
|
||||
|
||||
.line 39
|
||||
const/4 v7, 0x0
|
||||
|
||||
iput v7, v0, Lothers/TestInsnsBeforeSuper2;->mErrorType:I
|
||||
|
||||
.line 52
|
||||
iput v2, v0, Lothers/TestInsnsBeforeSuper2;->mErrorType:I
|
||||
|
||||
.line 53
|
||||
return-void
|
||||
.end method
|
||||
Reference in New Issue
Block a user