diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java index 387548eb3fc4f94c7f46ea329e01f73fe8762bdb..0f1e5b90f7f71b10acaf1fa83277b444a969f79f 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -40,6 +40,7 @@ import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnWrapArg; import jadx.core.dex.instructions.args.LiteralArg; import jadx.core.dex.instructions.args.Named; +import jadx.core.dex.instructions.args.NamedArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.SSAVar; import jadx.core.dex.instructions.mods.ConstructorInsn; @@ -874,6 +875,13 @@ public class InsnGen { if (Consts.DEBUG) { code.add("/* inline method: ").add(callMthNode.toString()).add("*/").startLine(); } + if (forceAssign(inl, insn, callMthNode)) { + ArgType varType = callMthNode.getReturnType(); + useType(code, varType); + code.add(' '); + code.add(mgen.getNameGen().assignNamedArg(new NamedArg("unused", varType))); + code.add(" = "); + } if (callMthNode.getMethodInfo().getArgumentsTypes().isEmpty()) { makeInsn(inl, code, Flags.BODY_ONLY); } else { @@ -907,6 +915,19 @@ public class InsnGen { return true; } + private boolean forceAssign(InsnNode inlineInsn, InvokeNode parentInsn, MethodNode callMthNode) { + if (parentInsn.getResult() != null) { + return false; + } + if (parentInsn.contains(AFlag.WRAPPED)) { + return false; + } + if (callMthNode.getReturnType().equals(ArgType.VOID)) { + return false; + } + return true; + } + private void makeTernary(TernaryInsn insn, CodeWriter code, Set state) throws CodegenException { boolean wrap = state.contains(Flags.BODY_ONLY); if (wrap) { diff --git a/jadx-core/src/test/java/jadx/tests/integration/inline/TestGetterInlineNegative.java b/jadx-core/src/test/java/jadx/tests/integration/inline/TestGetterInlineNegative.java new file mode 100644 index 0000000000000000000000000000000000000000..7ce971fe0f551a4799f35f3b3584f8d3c56a5779 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/integration/inline/TestGetterInlineNegative.java @@ -0,0 +1,43 @@ +package jadx.tests.integration.inline; + +import org.junit.jupiter.api.Test; + +import jadx.core.dex.nodes.ClassNode; +import jadx.tests.api.SmaliTest; + +import static jadx.tests.api.utils.JadxMatchers.containsOne; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.MatcherAssert.assertThat; + +public class TestGetterInlineNegative extends SmaliTest { + + // @formatter:off + /* + public class TestGetterInlineNegative { + public static final String field = "some string"; + + public static synthetic String getter() { + return field; + } + + public void test() { + getter(); // inline will produce 'field;' and fail to compile with 'not a statement' error + } + + public String test2() { + return getter(); + } + } + */ + // @formatter:on + + @Test + public void test() { + ClassNode cls = getClassNodeFromSmali(); + String code = cls.getCode().toString(); + + assertThat(code, not(containsString(indent() + "field;"))); + assertThat(code, containsOne("return field;")); + } +} diff --git a/jadx-core/src/test/smali/inline/TestGetterInlineNegative.smali b/jadx-core/src/test/smali/inline/TestGetterInlineNegative.smali new file mode 100644 index 0000000000000000000000000000000000000000..9456c87f161808bad947bba71b605625cf44ce44 --- /dev/null +++ b/jadx-core/src/test/smali/inline/TestGetterInlineNegative.smali @@ -0,0 +1,29 @@ +.class public Linline/TestGetterInlineNegative; +.super Ljava/lang/Object; + +.field public static final field:Ljava/lang/String; = "some string" + +.method public static synthetic getter()Ljava/lang/String; + .locals 1 + + sget-object v0, Linline/TestGetterInlineNegative;->field:Ljava/lang/String; + + return-object v0 +.end method + +.method public test()V + .locals 1 + + invoke-static {}, Linline/TestGetterInlineNegative;->getter()Ljava/lang/String; + + return-void +.end method + +.method public test2()Ljava/lang/String; + .locals 2 + + invoke-static {}, Linline/TestGetterInlineNegative;->getter()Ljava/lang/String; + move-result-object v1 + + return-object v1 +.end method