diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java index 1730cd394b6bbd7ac01b758adec90789d2f81c4a..b604a0c0a1e5e94c9285ae2a8269b5e3d721b27f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java @@ -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; } /** diff --git a/jadx-core/src/test/java/jadx/tests/integration/types/TestTypeResolver21.java b/jadx-core/src/test/java/jadx/tests/integration/types/TestTypeResolver21.java new file mode 100644 index 0000000000000000000000000000000000000000..1822ccd09237af2c9678d9f27a8a27d242b011b0 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/types/TestTypeResolver21.java @@ -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;"); + } +} diff --git a/jadx-core/src/test/smali/types/TestTypeResolver21.smali b/jadx-core/src/test/smali/types/TestTypeResolver21.smali new file mode 100644 index 0000000000000000000000000000000000000000..4665f2c7a6b85ebe0fb586a6267838a9c0b1d3d2 --- /dev/null +++ b/jadx-core/src/test/smali/types/TestTypeResolver21.smali @@ -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