Commit 8de6190a authored by Skylot's avatar Skylot

core: fix type inference for arguments in Phi node (fix #33)

parent d6e2c692
......@@ -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())) {
......
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);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment