Rewrite new-instance if type has been renamed
Code rewriter did not rewrite changed
types for new-instance instructions.
Test: ApplyMappingTest
Change-Id: I534ff493e8bc088b7d8b9308aa225d0848fff02c
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
index 9cd430a..cdb419f 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/LensCodeRewriter.java
@@ -30,6 +30,7 @@
import com.android.tools.r8.ir.code.InvokeMethod;
import com.android.tools.r8.ir.code.InvokeNewArray;
import com.android.tools.r8.ir.code.NewArrayEmpty;
+import com.android.tools.r8.ir.code.NewInstance;
import com.android.tools.r8.ir.code.StaticGet;
import com.android.tools.r8.ir.code.StaticPut;
import com.android.tools.r8.ir.code.Value;
@@ -196,7 +197,15 @@
newArrayEmpty.size(), newType);
iterator.replaceCurrentInstruction(newNewArray);
}
- }
+ } else if (current.isNewInstance()) {
+ NewInstance newInstance= current.asNewInstance();
+ DexType newClazz = graphLense.lookupType(newInstance.clazz, method);
+ if (newClazz != newInstance.clazz) {
+ NewInstance newNewInstance =
+ new NewInstance(newClazz, makeOutValue(newInstance, code));
+ iterator.replaceCurrentInstruction(newNewInstance);
+ }
+ }
}
}
assert code.isConsistentSSA();
diff --git a/src/test/examples/naming001/keep-rules-106.txt b/src/test/examples/naming001/keep-rules-106.txt
new file mode 100644
index 0000000..ca320eb
--- /dev/null
+++ b/src/test/examples/naming001/keep-rules-106.txt
@@ -0,0 +1,5 @@
+# Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+-applymapping mapping-106.txt
\ No newline at end of file
diff --git a/src/test/examples/naming001/mapping-106.txt b/src/test/examples/naming001/mapping-106.txt
new file mode 100644
index 0000000..1b3606d
--- /dev/null
+++ b/src/test/examples/naming001/mapping-106.txt
@@ -0,0 +1 @@
+naming001.E -> a.a:
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java b/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java
index 1631a52..276b763 100644
--- a/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java
@@ -15,6 +15,8 @@
import com.android.tools.r8.R8Command;
import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.code.Instruction;
+import com.android.tools.r8.code.NewInstance;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.shaking.ProguardRuleParserException;
@@ -219,13 +221,40 @@
main.iterateInstructions(InstructionSubject::isInvoke);
// mapping-105 simply includes: naming001.D#keep -> peek
// naming001.E extends D, hence its keep() should be renamed to peek as well.
- // Skip E#<init>
- iterator.next();
+ // Check E#<init> is not renamed.
+ InvokeInstructionSubject init = iterator.next();
+ assertEquals("Lnaming001/E;-><init>()V", init.invokedMethod().toSmaliString());
// E#keep() should be replaced with peek by applying the map.
InvokeInstructionSubject m = iterator.next();
assertEquals("peek", m.invokedMethod().name.toSourceString());
- // E could be renamed randomly, though.
- assertNotEquals("naming001.E", m.holder().toString());
+ // D must not be renamed
+ assertEquals("naming001.D", m.holder().toString());
+ }
+
+ @Test
+ public void test_naming001_rule106() throws Exception {
+ // keep rules just to rename E
+ Path flag = Paths.get(ToolHelper.EXAMPLES_DIR, "naming001", "keep-rules-106.txt");
+ Path proguardMap = out.resolve(MAPPING);
+ AndroidApp outputApp =
+ runR8(
+ ToolHelper.addProguardConfigurationConsumer(
+ getCommandForApps(out, flag, NAMING001_JAR).setDisableMinification(true),
+ pgConfig -> {
+ pgConfig.setPrintMapping(true);
+ pgConfig.setPrintMappingFile(proguardMap);
+ })
+ .build());
+
+ // Make sure the given proguard map is indeed applied.
+ DexInspector inspector = new DexInspector(outputApp);
+ MethodSubject main = inspector.clazz("naming001.D").method(DexInspector.MAIN);
+
+ // naming001.E is renamed to a.a, so first instruction must be: new-instance La/a;
+ Instruction[] instructions = main.getMethod().getCode().asDexCode().instructions;
+ assertTrue(instructions[0] instanceof NewInstance);
+ NewInstance newInstance = (NewInstance) instructions[0];
+ assertEquals( "La/a;", newInstance.getType().toSmaliString());
}
@Test