fix: keep types on duplicate cast remove (#1527)
This commit is contained in:
@@ -362,8 +362,7 @@ public class ModVisitor extends AbstractVisitor {
|
||||
private static void removeCheckCast(MethodNode mth, BlockNode block, int i, IndexInsnNode insn) {
|
||||
InsnArg castArg = insn.getArg(0);
|
||||
ArgType castType = (ArgType) insn.getIndex();
|
||||
if (!ArgType.isCastNeeded(mth.root(), castArg.getType(), castType)
|
||||
|| isCastDuplicate(insn)) {
|
||||
if (!ArgType.isCastNeeded(mth.root(), castArg.getType(), castType)) {
|
||||
RegisterArg result = insn.getResult();
|
||||
result.setType(castArg.getType());
|
||||
|
||||
@@ -371,10 +370,19 @@ public class ModVisitor extends AbstractVisitor {
|
||||
move.setResult(result);
|
||||
move.addArg(castArg);
|
||||
replaceInsn(mth, block, i, move);
|
||||
return;
|
||||
}
|
||||
InsnNode prevCast = isCastDuplicate(insn);
|
||||
if (prevCast != null) {
|
||||
// replace previous cast with move
|
||||
InsnNode move = new InsnNode(InsnType.MOVE, 1);
|
||||
move.setResult(prevCast.getResult());
|
||||
move.addArg(prevCast.getArg(0));
|
||||
replaceInsn(mth, block, prevCast, move);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isCastDuplicate(IndexInsnNode castInsn) {
|
||||
private static @Nullable InsnNode isCastDuplicate(IndexInsnNode castInsn) {
|
||||
InsnArg arg = castInsn.getArg(0);
|
||||
if (arg.isRegister()) {
|
||||
SSAVar sVar = ((RegisterArg) arg).getSVar();
|
||||
@@ -382,11 +390,13 @@ public class ModVisitor extends AbstractVisitor {
|
||||
InsnNode assignInsn = sVar.getAssign().getParentInsn();
|
||||
if (assignInsn != null && assignInsn.getType() == InsnType.CHECK_CAST) {
|
||||
ArgType assignCastType = (ArgType) ((IndexInsnNode) assignInsn).getIndex();
|
||||
return assignCastType.equals(castInsn.getIndex());
|
||||
if (assignCastType.equals(castInsn.getIndex())) {
|
||||
return assignInsn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package jadx.tests.integration.types;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
/**
|
||||
* Issue 1527
|
||||
*/
|
||||
@SuppressWarnings("CommentedOutCode")
|
||||
public class TestTypeResolver21 extends SmaliTest {
|
||||
// @formatter:off
|
||||
/*
|
||||
public Number test(Object objectArray) {
|
||||
Object[] arr = (Object[]) objectArray;
|
||||
return (Number) arr[0];
|
||||
}
|
||||
*/
|
||||
// @formatter:on
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertThat(getClassNodeFromSmali())
|
||||
.code()
|
||||
.containsOne("Object[] arr = (Object[]) objectArray;");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
.class public Ltypes/TestTypeResolver21;
|
||||
.super Ljava/lang/Object;
|
||||
.source "TestTypeResolver21.java"
|
||||
|
||||
|
||||
.method public test(Ljava/lang/Object;)Ljava/lang/Number;
|
||||
.registers 4
|
||||
.param p1, "objectArray" # Ljava/lang/Object;
|
||||
|
||||
.prologue
|
||||
.line 16
|
||||
check-cast p1, [Ljava/lang/Object;
|
||||
.end local p1 # "objectArray":Ljava/lang/Object;
|
||||
move-object v0, p1
|
||||
check-cast v0, [Ljava/lang/Object;
|
||||
|
||||
.line 17
|
||||
.local v0, "arr":[Ljava/lang/Object;
|
||||
const/4 v1, 0x0
|
||||
aget-object v1, v0, v1
|
||||
check-cast v1, Ljava/lang/Number;
|
||||
return-object v1
|
||||
.end method
|
||||
Reference in New Issue
Block a user