fix: don't inline constants in synchronized statement (#799)
This commit is contained in:
@@ -82,6 +82,10 @@ public class ConstInlineVisitor extends AbstractVisitor {
|
||||
}
|
||||
return;
|
||||
}
|
||||
// don't inline const values in synchronized statement
|
||||
if (checkForSynchronizeBlock(insn, sVar)) {
|
||||
return;
|
||||
}
|
||||
} else if (insnType == InsnType.CONST_STR) {
|
||||
if (sVar.isUsedInPhi()) {
|
||||
return;
|
||||
@@ -108,6 +112,20 @@ public class ConstInlineVisitor extends AbstractVisitor {
|
||||
replaceConst(mth, insn, constArg, toRemove);
|
||||
}
|
||||
|
||||
private static boolean checkForSynchronizeBlock(InsnNode insn, SSAVar ssaVar) {
|
||||
for (RegisterArg reg : ssaVar.getUseList()) {
|
||||
InsnNode parentInsn = reg.getParentInsn();
|
||||
if (parentInsn != null) {
|
||||
InsnType insnType = parentInsn.getType();
|
||||
if (insnType == InsnType.MONITOR_ENTER || insnType == InsnType.MONITOR_EXIT) {
|
||||
insn.add(AFlag.DONT_INLINE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean checkForFinallyBlock(SSAVar sVar) {
|
||||
List<SSAVar> ssaVars = sVar.getCodeVar().getSsaVars();
|
||||
if (ssaVars.size() <= 1) {
|
||||
|
||||
@@ -608,6 +608,7 @@ public class RegionMaker {
|
||||
visited.add(block);
|
||||
for (InsnNode insn : block.getInstructions()) {
|
||||
if (insn.getType() == InsnType.MONITOR_EXIT
|
||||
&& insn.getArgsCount() > 0
|
||||
&& insn.getArg(0).equals(arg)) {
|
||||
exits.add(block);
|
||||
region.getExitInsns().add(insn);
|
||||
|
||||
@@ -16,6 +16,8 @@ public class JadxClassNodeAssertions extends AbstractAssert<JadxClassNodeAsserti
|
||||
isNotNull();
|
||||
ICodeInfo code = actual.getCode();
|
||||
assertThat(code).isNotNull();
|
||||
return new JadxCodeAssertions(code.getCodeStr());
|
||||
String codeStr = code.getCodeStr();
|
||||
assertThat(codeStr).isNotBlank();
|
||||
return new JadxCodeAssertions(codeStr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package jadx.tests.integration.synchronize;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import jadx.tests.api.SmaliTest;
|
||||
|
||||
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
|
||||
|
||||
public class TestNestedSynchronize extends SmaliTest {
|
||||
|
||||
// @formatter:off
|
||||
/*
|
||||
public final void test() {
|
||||
Object obj = null;
|
||||
Object obj2 = null;
|
||||
synchronized (obj) {
|
||||
synchronized (obj2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
// @formatter:on
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
assertThat(getClassNodeFromSmali())
|
||||
.code()
|
||||
.countString(2, "synchronized");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
.class public final Lsynchronize/TestNestedSynchronize;
|
||||
.super Ljava/lang/Object;
|
||||
.source "TestNestedSynchronize.java"
|
||||
|
||||
.method public final test()V
|
||||
.locals 2
|
||||
const/4 v0, 0
|
||||
const/4 v1, 0
|
||||
monitor-enter v0
|
||||
monitor-enter v1
|
||||
monitor-exit v1
|
||||
monitor-exit v0
|
||||
return-void
|
||||
.end method
|
||||
Reference in New Issue
Block a user