diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java index 869a50bb1..cf35cc5eb 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/InsnArg.java @@ -65,6 +65,7 @@ public abstract class InsnArg extends Typed { } private static InsnWrapArg wrap(InsnNode insn) { + insn.add(AFlag.WRAPPED); return new InsnWrapArg(insn); } @@ -140,9 +141,17 @@ public abstract class InsnArg extends Typed { InsnArg arg; InsnType type = insn.getType(); if (type == InsnType.CONST || type == InsnType.MOVE) { - arg = insn.getArg(0); - insn.add(AFlag.REMOVE); - insn.add(AFlag.DONT_GENERATE); + if (insn.contains(AFlag.FORCE_ASSIGN_INLINE)) { + RegisterArg resArg = insn.getResult(); + arg = wrap(insn); + if (resArg != null) { + arg.setType(resArg.getType()); + } + } else { + arg = insn.getArg(0); + insn.add(AFlag.REMOVE); + insn.add(AFlag.DONT_GENERATE); + } } else { arg = wrapArg(insn); } @@ -156,8 +165,6 @@ public abstract class InsnArg extends Typed { public static InsnArg wrapArg(InsnNode insn) { RegisterArg resArg = insn.getResult(); InsnArg arg = wrap(insn); - insn.add(AFlag.WRAPPED); - switch (insn.getType()) { case CONST: case MOVE: diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/shrink/CodeShrinkVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/shrink/CodeShrinkVisitor.java index 1cfb9d643..40d731ce7 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/shrink/CodeShrinkVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/shrink/CodeShrinkVisitor.java @@ -100,10 +100,6 @@ public class CodeShrinkVisitor extends AbstractVisitor { int assignPos = insnList.getIndex(assignInsn); if (assignPos != -1) { - if (assignInline) { - // TODO? - return; - } WrapInfo wrapInfo = argsInfo.checkInline(assignPos, arg); if (wrapInfo != null) { wrapList.add(wrapInfo); @@ -123,25 +119,19 @@ public class CodeShrinkVisitor extends AbstractVisitor { } } - private static void assignInline(MethodNode mth, RegisterArg arg, InsnNode assignInsn, BlockNode assignBlock) { + private static boolean assignInline(MethodNode mth, RegisterArg arg, InsnNode assignInsn, BlockNode assignBlock) { RegisterArg useArg = arg.getSVar().getUseList().get(0); InsnNode useInsn = useArg.getParentInsn(); if (useInsn == null || useInsn.contains(AFlag.DONT_GENERATE)) { - return; - } - - InsnArg replaceArg; - InsnType assignInsnType = assignInsn.getType(); - if (assignInsnType == InsnType.MOVE || assignInsnType == InsnType.CONST) { - replaceArg = assignInsn.getArg(0).duplicate(); - } else { - replaceArg = InsnArg.wrapArg(assignInsn.copy()); + return false; } + InsnArg replaceArg = InsnArg.wrapInsnIntoArg(assignInsn.copy()); useInsn.replaceArg(useArg, replaceArg); assignInsn.add(AFlag.REMOVE); assignInsn.add(AFlag.DONT_GENERATE); InsnRemover.remove(mth, assignBlock, assignInsn); + return true; } private static boolean inline(MethodNode mth, RegisterArg arg, InsnNode insn, BlockNode block) { @@ -149,6 +139,9 @@ public class CodeShrinkVisitor extends AbstractVisitor { if (parentInsn != null && parentInsn.getType() == InsnType.RETURN) { parentInsn.setSourceLine(insn.getSourceLine()); } + if (insn.contains(AFlag.FORCE_ASSIGN_INLINE)) { + return assignInline(mth, arg, insn, block); + } boolean replaced = arg.wrapInstruction(mth, insn) != null; if (replaced) { InsnList.remove(block, insn); diff --git a/jadx-core/src/test/java/jadx/tests/integration/conditions/TestInnerAssign3.java b/jadx-core/src/test/java/jadx/tests/integration/conditions/TestInnerAssign3.java new file mode 100644 index 000000000..e6ef2f700 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/conditions/TestInnerAssign3.java @@ -0,0 +1,22 @@ +package jadx.tests.integration.conditions; + +import org.junit.jupiter.api.Test; + +import jadx.tests.api.SmaliTest; + +import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat; + +/** + * Issue #820 + */ +public class TestInnerAssign3 extends SmaliTest { + + @Test + public void test() { + disableCompilation(); + assertThat(getClassNodeFromSmali()) + .code() + .containsOne("(testMethod = (testClass1 = null).testMethod()) == null") + .containsOne("testClass1.testField != null"); + } +} diff --git a/jadx-core/src/test/smali/conditions/TestInnerAssign3.smali b/jadx-core/src/test/smali/conditions/TestInnerAssign3.smali new file mode 100644 index 000000000..a24878423 --- /dev/null +++ b/jadx-core/src/test/smali/conditions/TestInnerAssign3.smali @@ -0,0 +1,30 @@ +.class public Lconditions/TestInnerAssign3; +.super LTestSuper; +.source "Test.java" + +.method public test()V + .locals 5 + + const/4 v0, 0 + const/4 v1, 0 + const/4 v4, 0 + + if-eqz v4, :cond_0 + + const/4 v2, 0 + + invoke-virtual {v2}, LTestClass1;->testMethod()LTestClass2; + + move-result-object v0 + + if-eqz v0, :cond_0 + + if-eq v1, v0, :cond_0 + + iget-object v3, v2, LTestClass1;->testField:LTestClass3; + + if-eqz v3, :cond_0 + + :cond_0 + return-void +.end method