core: fix type inference for arguments in Phi node (fix #33)
This commit is contained in:
+25
-9
@@ -8,7 +8,6 @@ import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.instructions.args.InsnArg;
|
||||
import jadx.core.dex.instructions.args.LiteralArg;
|
||||
import jadx.core.dex.instructions.args.RegisterArg;
|
||||
import jadx.core.dex.instructions.args.SSAVar;
|
||||
import jadx.core.dex.nodes.InsnNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
|
||||
@@ -100,18 +99,26 @@ public class PostTypeInference {
|
||||
|
||||
case PHI: {
|
||||
PhiInsn phi = (PhiInsn) insn;
|
||||
RegisterArg result = phi.getResult();
|
||||
SSAVar resultSVar = result.getSVar();
|
||||
if (resultSVar != null && !result.getType().isTypeKnown()) {
|
||||
ArgType type = phi.getResult().getType();
|
||||
if (!type.isTypeKnown()) {
|
||||
for (InsnArg arg : phi.getArguments()) {
|
||||
ArgType argType = arg.getType();
|
||||
if (argType.isTypeKnown()) {
|
||||
resultSVar.setType(argType);
|
||||
return true;
|
||||
if (arg.getType().isTypeKnown()) {
|
||||
type = arg.getType();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
boolean changed = false;
|
||||
if (updateType(phi.getResult(), type)) {
|
||||
changed = true;
|
||||
}
|
||||
for (int i = 0; i < phi.getArgsCount(); i++) {
|
||||
RegisterArg arg = phi.getArg(i);
|
||||
if (updateType(arg, type)) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -120,6 +127,15 @@ public class PostTypeInference {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean updateType(RegisterArg arg, ArgType type) {
|
||||
ArgType prevType = arg.getType();
|
||||
if (prevType == null || !prevType.equals(type)) {
|
||||
arg.setType(type);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean fixArrayTypes(InsnArg array, InsnArg elem) {
|
||||
boolean change = false;
|
||||
if (!elem.getType().isTypeKnown() && elem.merge(array.getType().getArrayElement())) {
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package jadx.tests.integration.types;
|
||||
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static jadx.tests.api.utils.JadxMatchers.containsOne;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class TestTypeResolver3 extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
|
||||
public int test(String s1, String s2) {
|
||||
int cmp = s2.compareTo(s1);
|
||||
if (cmp != 0) {
|
||||
return cmp;
|
||||
}
|
||||
return s1.length() == s2.length() ? 0 : s1.length() < s2.length() ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
// TODO inline into return
|
||||
assertThat(code, containsOne("s1.length() == s2.length() ? 0 : s1.length() < s2.length() ? -1 : 1;"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
noDebugInfo();
|
||||
getClassNode(TestCls.class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user