提交 0deafb76 编写于 作者: S Skylot

fix: correct merge code variables across PHI instructions (#930)

上级 cd612b45
......@@ -166,6 +166,27 @@ public class SSAVar {
return usedInPhi;
}
/**
* Concat assign PHI insn and usedInPhi
*/
public List<PhiInsn> getPhiList() {
InsnNode assignInsn = getAssign().getParentInsn();
if (assignInsn != null && assignInsn.getType() == InsnType.PHI) {
PhiInsn assignPhi = (PhiInsn) assignInsn;
if (usedInPhi == null) {
return Collections.singletonList(assignPhi);
}
List<PhiInsn> list = new ArrayList<>(1 + usedInPhi.size());
list.add(assignPhi);
list.addAll(usedInPhi);
return list;
}
if (usedInPhi == null) {
return Collections.emptyList();
}
return usedInPhi;
}
public boolean isUsedInPhi() {
return usedInPhi != null && !usedInPhi.isEmpty();
}
......
......@@ -70,11 +70,11 @@ public class InitCodeVariables extends AbstractVisitor {
}
private static void setCodeVar(SSAVar ssaVar, CodeVar codeVar) {
List<PhiInsn> usedInPhiList = ssaVar.getUsedInPhi();
if (!usedInPhiList.isEmpty()) {
List<PhiInsn> phiList = ssaVar.getPhiList();
if (!phiList.isEmpty()) {
Set<SSAVar> vars = new LinkedHashSet<>();
vars.add(ssaVar);
collectConnectedVars(usedInPhiList, vars);
collectConnectedVars(phiList, vars);
setCodeVarType(codeVar, vars);
vars.forEach(var -> {
if (var.isCodeVarSet()) {
......@@ -105,15 +105,18 @@ public class InitCodeVariables extends AbstractVisitor {
}
private static void collectConnectedVars(List<PhiInsn> phiInsnList, Set<SSAVar> vars) {
if (phiInsnList.isEmpty()) {
return;
}
for (PhiInsn phiInsn : phiInsnList) {
SSAVar resultVar = phiInsn.getResult().getSVar();
if (vars.add(resultVar)) {
collectConnectedVars(resultVar.getUsedInPhi(), vars);
collectConnectedVars(resultVar.getPhiList(), vars);
}
phiInsn.getArguments().forEach(arg -> {
SSAVar sVar = ((RegisterArg) arg).getSVar();
if (vars.add(sVar)) {
collectConnectedVars(sVar.getUsedInPhi(), vars);
collectConnectedVars(sVar.getPhiList(), vars);
}
});
}
......
package jadx.tests.integration.variables;
import org.junit.jupiter.api.Test;
import jadx.tests.api.SmaliTest;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestVariablesInLoop extends SmaliTest {
@Test
public void test() {
assertThat(getClassNodeFromSmali())
.code()
.containsOne("int i;")
.countString(2, "i = 0;")
.doesNotContain("i3");
}
}
.class public abstract Lvariables/TestVariablesInLoop;
.super Ljava/lang/Object;
.source "SourceFile"
.implements Ljava/util/List;
.annotation system Ldalvik/annotation/Signature;
value = {
"Ljava/lang/Object;",
"Ljava/util/List<",
"Ljava/lang/Long;",
">;"
}
.end annotation
.method static test(Ljava/util/List;)I
.locals 5
.annotation system Ldalvik/annotation/Signature;
value = {
"(",
"Ljava/util/List<",
"Ljava/lang/Long;",
">;)I"
}
.end annotation
invoke-interface {p0}, Ljava/util/List;->size()I
move-result v0
const/4 v1, 0x0
if-nez v0, :cond_0
return v1
:cond_0
instance-of v2, p0, Lvariables/TestVariablesInLoop;
if-eqz v2, :cond_1
check-cast p0, Lvariables/TestVariablesInLoop;
const/4 v2, 0x0
:goto_0
if-ge v1, v0, :cond_2
invoke-virtual {p0, v1}, Lvariables/TestVariablesInLoop;->getLong(I)J
move-result-wide v3
invoke-static {v3, v4}, Lvariables/TestVariablesInLoop;->mth(J)I
move-result v3
add-int/2addr v2, v3
add-int/lit8 v1, v1, 0x1
goto :goto_0
:cond_1
const/4 v2, 0x0
:goto_1
if-ge v1, v0, :cond_2
invoke-interface {p0, v1}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v3
check-cast v3, Ljava/lang/Long;
invoke-virtual {v3}, Ljava/lang/Long;->longValue()J
move-result-wide v3
invoke-static {v3, v4}, Lvariables/TestVariablesInLoop;->mth(J)I
move-result v3
add-int/2addr v2, v3
add-int/lit8 v1, v1, 0x1
goto :goto_1
:cond_2
return v2
.end method
.method public final getLong(I)J
.locals 2
const/16 v0, 0x0
return-wide v0
.end method
.method static mth(J)I
.locals 2
const/4 v0, 0x0
return v0
.end method
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册