Enable new argument propagation
Change-Id: Iade5f22bffaf9d3283b8e5f3d78772a8c04a5c60
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 2a44d85..4a6a664 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1219,7 +1219,7 @@
// TODO(b/69963623): enable if everything is ready, including signature rewriting at call sites.
private boolean enableLegacyConstantPropagation = false;
- private boolean enableExperimentalArgumentPropagation = false;
+ private boolean enableExperimentalArgumentPropagation = true;
private boolean enableDynamicTypePropagation = true;
public void disableOptimization() {
@@ -1255,7 +1255,7 @@
}
public CallSiteOptimizationOptions setEnableLegacyConstantPropagation() {
- assert !isConstantPropagationEnabled();
+ assert !enableLegacyConstantPropagation;
enableLegacyConstantPropagation = true;
return this;
}
diff --git a/src/test/examples/shaking14/KeepConstantArguments.java b/src/test/examples/shaking14/KeepConstantArguments.java
new file mode 100644
index 0000000..0ff3910
--- /dev/null
+++ b/src/test/examples/shaking14/KeepConstantArguments.java
@@ -0,0 +1,13 @@
+// Copyright (c) 2021, 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.
+package shaking14;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.METHOD})
+public @interface KeepConstantArguments {}
diff --git a/src/test/examples/shaking14/Subclass.java b/src/test/examples/shaking14/Subclass.java
index 31dd650..2cb520a 100644
--- a/src/test/examples/shaking14/Subclass.java
+++ b/src/test/examples/shaking14/Subclass.java
@@ -4,10 +4,13 @@
package shaking14;
public class Subclass extends Superclass {
+
+ @KeepConstantArguments
static int aMethod(int value) {
return value + 42;
}
+ @KeepConstantArguments
static double anotherMethod(double value) {
return value + 42;
}
diff --git a/src/test/examples/shaking14/keep-rules.txt b/src/test/examples/shaking14/keep-rules.txt
index 94682a3..594e244 100644
--- a/src/test/examples/shaking14/keep-rules.txt
+++ b/src/test/examples/shaking14/keep-rules.txt
@@ -10,3 +10,4 @@
# allow access modification to enable minifcation
-allowaccessmodification
+-keepconstantarguments class * { @shaking14.KeepConstantArguments *; }
diff --git a/src/test/java/com/android/tools/r8/KeepConstantArguments.java b/src/test/java/com/android/tools/r8/KeepConstantArguments.java
index 87edb4f..132b92d 100644
--- a/src/test/java/com/android/tools/r8/KeepConstantArguments.java
+++ b/src/test/java/com/android/tools/r8/KeepConstantArguments.java
@@ -4,7 +4,10 @@
package com.android.tools.r8;
import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.CLASS)
+@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface KeepConstantArguments {}
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index c81cdfc..188f23f 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -1287,8 +1287,16 @@
private static Map<String, List<String>> keepRules =
ImmutableMap.of(
- "021-string2", ImmutableList.of("-dontwarn junit.framework.**"),
- "082-inline-execute", ImmutableList.of("-dontwarn junit.framework.**"));
+ "021-string2",
+ ImmutableList.of("-dontwarn junit.framework.**"),
+ "082-inline-execute",
+ ImmutableList.of("-dontwarn junit.framework.**"),
+ // Constructor MakeBoundType.<init>(int) is called using reflection.
+ "476-checker-ctor-fence-redun-elim",
+ ImmutableList.of(
+ "-keep class TestDontOptimizeAcrossEscape$MakeBoundTypeTest$MakeBoundType {",
+ " void <init>(int);",
+ "}"));
private static Map<String, Consumer<InternalOptions>> configurations =
ImmutableMap.of(
diff --git a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
index fb37493..08dd682 100644
--- a/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunExamplesAndroidOTest.java
@@ -120,7 +120,7 @@
.withOptionConsumer(opts -> opts.enableClassInlining = false)
.withBuilderTransformation(
b -> b.addProguardConfiguration(PROGUARD_OPTIONS, Origin.unknown()))
- .withDexCheck(inspector -> checkLambdaCount(inspector, 10, "lambdadesugaring"))
+ .withDexCheck(inspector -> checkLambdaCount(inspector, 9, "lambdadesugaring"))
.run();
test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
@@ -159,7 +159,7 @@
.withOptionConsumer(opts -> opts.enableClassInlining = false)
.withBuilderTransformation(
b -> b.addProguardConfiguration(PROGUARD_OPTIONS, Origin.unknown()))
- .withDexCheck(inspector -> checkLambdaCount(inspector, 10, "lambdadesugaring"))
+ .withDexCheck(inspector -> checkLambdaCount(inspector, 9, "lambdadesugaring"))
.run();
test("lambdadesugaring", "lambdadesugaring", "LambdaDesugaring")
@@ -204,7 +204,7 @@
b ->
b.addProguardConfiguration(
getProguardOptionsNPlus(enableProguardCompatibilityMode), Origin.unknown()))
- .withDexCheck(inspector -> checkLambdaCount(inspector, 2, "lambdadesugaringnplus"))
+ .withDexCheck(inspector -> checkLambdaCount(inspector, 3, "lambdadesugaringnplus"))
.run();
}
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java
index 8cd7860..6bf8cf9 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/NonConstructorRelaxationTest.java
@@ -78,6 +78,7 @@
R8TestRunResult result =
testForR8(parameters.getBackend())
.addProgramFiles(ToolHelper.getClassFilesForTestPackage(mainClass.getPackage()))
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
.enableMemberValuePropagationAnnotations()
@@ -162,6 +163,7 @@
.addProgramFiles(ToolHelper.getClassFilesForTestPackage(mainClass.getPackage()))
.addKeepMainRule(mainClass)
.addOptionsModification(o -> o.enableVerticalClassMerging = enableVerticalClassMerging)
+ .enableConstantArgumentAnnotations()
.enableNeverClassInliningAnnotations()
.enableInliningAnnotations()
.enableMemberValuePropagationAnnotations()
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/privateinstance/Sub1.java b/src/test/java/com/android/tools/r8/accessrelaxation/privateinstance/Sub1.java
index c832fe7..7974306 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/privateinstance/Sub1.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/privateinstance/Sub1.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.accessrelaxation.privateinstance;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
@@ -16,6 +17,7 @@
return "Sub1::foo1()";
}
+ @KeepConstantArguments
@NeverInline
private String bar1(int i) {
return "Sub1::bar1(" + i + ")";
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/privateinstance/Sub2.java b/src/test/java/com/android/tools/r8/accessrelaxation/privateinstance/Sub2.java
index ffdeec6..6e8d5f7 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/privateinstance/Sub2.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/privateinstance/Sub2.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.accessrelaxation.privateinstance;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
@@ -16,6 +17,7 @@
return "Sub2::foo2()";
}
+ @KeepConstantArguments
@NeverInline
private String bar1(int i) {
return "Sub2::bar1(" + i + ")";
@@ -25,6 +27,7 @@
return bar1(1);
}
+ @KeepConstantArguments
@NeverInline
private String bar2(int i) {
return "Sub2::bar2(" + i + ")";
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/A.java b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/A.java
index a05f41f..a0c3330 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/A.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/A.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.accessrelaxation.privatestatic;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NeverPropagateValue;
@@ -42,6 +43,7 @@
return bar(1);
}
+ @KeepConstantArguments
@NeverInline
@NeverPropagateValue
private static String blah(int i) {
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/BB.java b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/BB.java
index a6c40ff..d458af8 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/BB.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/privatestatic/BB.java
@@ -4,12 +4,15 @@
package com.android.tools.r8.accessrelaxation.privatestatic;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NeverPropagateValue;
import com.android.tools.r8.NoHorizontalClassMerging;
@NoHorizontalClassMerging
public class BB extends A {
+
+ @KeepConstantArguments
@NeverInline
@NeverPropagateValue
private static String blah(int i) {
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelInterfaceTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelInterfaceTest.java
index 602f4a1..bdaf09d 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelNoInliningOfHigherApiLevelInterfaceTest.java
@@ -7,6 +7,7 @@
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForMethod;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.verifyThat;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
import com.android.tools.r8.TestBase;
@@ -44,6 +45,7 @@
.addDefaultRuntimeLibrary(parameters)
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(Main.class)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
.apply(setMockApiLevelForMethod(apiMethod, AndroidApiLevel.L_MR1))
@@ -63,6 +65,7 @@
@NoHorizontalClassMerging
public static class ApiCaller {
+ @KeepConstantArguments
public static void callInterfaceMethod(Api api) {
System.out.println("ApiCaller::callInterfaceMethod");
if (api != null) {
diff --git a/src/test/java/com/android/tools/r8/bridgeremoval/B77836766.java b/src/test/java/com/android/tools/r8/bridgeremoval/B77836766.java
index 07ad8f0..1790724 100644
--- a/src/test/java/com/android/tools/r8/bridgeremoval/B77836766.java
+++ b/src/test/java/com/android/tools/r8/bridgeremoval/B77836766.java
@@ -8,6 +8,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
@@ -93,6 +94,7 @@
ClassBuilder cls1 = jasminBuilder.addClass("Cls1", absCls.name, itf1.name);
// Mimic Kotlin's "internal" class
cls1.setAccess("");
+ cls1.addRuntimeInvisibleAnnotation(KeepConstantArguments.class.getTypeName());
cls1.addBridgeMethod("foo", ImmutableList.of("Ljava/lang/String;"), "V",
".limit stack 2",
".limit locals 2",
@@ -143,6 +145,7 @@
.addProgramClassFileData(jasminBuilder.buildClasses())
.addKeepMainRule(mainClass.name)
.addOptionsModification(this::configure)
+ .enableConstantArgumentAnnotations()
.noHorizontalClassMerging(cls2Class.name)
.noMinification()
.setMinApi(parameters.getApiLevel())
@@ -239,6 +242,7 @@
"return");
ClassBuilder cls2 = jasminBuilder.addClass("DerivedString", baseCls.name);
+ cls2.addRuntimeInvisibleAnnotation(KeepConstantArguments.class.getTypeName());
cls2.addVirtualMethod("bar", ImmutableList.of("Ljava/lang/String;"), "V",
".limit stack 2",
".limit locals 2",
@@ -272,6 +276,7 @@
.addProgramClassFileData(jasminBuilder.buildClasses())
.addKeepMainRule(mainClass.name)
.addOptionsModification(this::configure)
+ .enableConstantArgumentAnnotations()
.noHorizontalClassMerging(derivedIntegerClass.name)
.noMinification()
.setMinApi(parameters.getApiLevel())
@@ -347,6 +352,7 @@
"return");
ClassBuilder subCls = jasminBuilder.addClass("DerivedString", baseCls.name);
+ subCls.addRuntimeInvisibleAnnotation(KeepConstantArguments.class.getTypeName());
subCls.addVirtualMethod("bar", ImmutableList.of("Ljava/lang/String;"), "V",
".limit stack 2",
".limit locals 2",
@@ -381,6 +387,7 @@
.addProgramClassFileData(jasminBuilder.buildClasses())
.addKeepMainRule(mainClass.name)
.addOptionsModification(this::configure)
+ .enableConstantArgumentAnnotations()
.noMinification()
.setMinApi(parameters.getApiLevel())
.compile()
@@ -433,6 +440,7 @@
"aload_1",
"invokevirtual java/io/PrintStream/print(Ljava/lang/Object;)V",
"return");
+ cls.addRuntimeInvisibleAnnotation(KeepConstantArguments.class.getTypeName());
cls.addVirtualMethod("bar", ImmutableList.of("Ljava/lang/String;"), "V",
".limit stack 2",
".limit locals 2",
@@ -467,6 +475,7 @@
.addProgramClassFileData(jasminBuilder.buildClasses())
.addKeepMainRule(mainClass.name)
.addOptionsModification(this::configure)
+ .enableConstantArgumentAnnotations()
.noMinification()
.setMinApi(parameters.getApiLevel())
.compile()
@@ -495,7 +504,6 @@
// Callees are invoked with a simple constant, e.g., "Bar". Propagating it into the callees
// bothers what the tests want to check, such as exact instructions in the body that include
// invocation kinds, like virtual call to a bridge.
- assert !options.callSiteOptimizationOptions().isConstantPropagationEnabled();
// Disable inlining to avoid the (short) tested method from being inlined and then removed.
options.enableInlining = false;
}
diff --git a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/BridgeHoistingAccessibilityTest.java b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/BridgeHoistingAccessibilityTest.java
index 81c5c04..45855d8 100644
--- a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/BridgeHoistingAccessibilityTest.java
+++ b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/BridgeHoistingAccessibilityTest.java
@@ -6,6 +6,7 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoVerticalClassMerging;
@@ -71,6 +72,7 @@
int.class))
.transform())
.addKeepMainRule(TestClass.class)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
.enableNoVerticalClassMergingAnnotations()
@@ -119,6 +121,7 @@
// This bridge cannot be hoisted to A, since it would then become inaccessible to the call site
// in TestClass.main().
+ @KeepConstantArguments
@NeverInline
/*bridge*/ String bridgeB(Object o) {
return (String) m((String) o);
@@ -131,6 +134,7 @@
// This bridge is invoked from another package. However, this does not prevent us from hoisting
// the bridge to B, although B is not public, since users from outside this package can still
// access bridgeC() via class C. From B, the bridge can be hoisted again to A.
+ @KeepConstantArguments
@NeverInline
public /*bridge*/ String bridgeC(Object o) {
return (String) m((String) o);
@@ -142,6 +146,7 @@
// This bridge cannot be hoisted to A, since it would then become inaccessible to the call site
// in TestClass.main().
+ @KeepConstantArguments
@NeverInline
/*bridge*/ String bridgeB(Object o, int a, int b, int c, int d, int e) {
return (String) m((String) o, a, b, c, d, e);
@@ -154,6 +159,7 @@
// This bridge is invoked from another package. However, this does not prevent us from hoisting
// the bridge to B, although B is not public, since users from outside this package can still
// access bridgeC() via class C. From B, the bridge can be hoisted again to A.
+ @KeepConstantArguments
@NeverInline
public /*bridge*/ String bridgeC(Object o, int a, int b, int c, int d, int e) {
return (String) m((String) o, a, b, c, d, e);
diff --git a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/FinalBridgeHoistingTest.java b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/FinalBridgeHoistingTest.java
index de2e041..bf958f8 100644
--- a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/FinalBridgeHoistingTest.java
+++ b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/FinalBridgeHoistingTest.java
@@ -7,6 +7,7 @@
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
@@ -42,6 +43,7 @@
.transform())
.addKeepMainRule(TestClass.class)
.addKeepClassAndMembersRules(B1.class)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.setMinApi(parameters.getApiLevel())
@@ -85,6 +87,7 @@
@NeverClassInline
static class B1 extends A {
+ @KeepConstantArguments
public String virtualBridge(Object o) {
return (String) m((String) o);
}
@@ -93,6 +96,7 @@
@NeverClassInline
static class B2 extends A {
+ @KeepConstantArguments
@NeverInline
public final /*bridge*/ String virtualBridge(Object o) {
return (String) m((String) o);
diff --git a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/NonSuperclassBridgeHoistingTest.java b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/NonSuperclassBridgeHoistingTest.java
index f2a91a8..e987a43 100644
--- a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/NonSuperclassBridgeHoistingTest.java
+++ b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/NonSuperclassBridgeHoistingTest.java
@@ -7,6 +7,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoVerticalClassMerging;
@@ -42,6 +43,7 @@
.setBridge(B.class.getDeclaredMethod("bridge", Object.class))
.transform())
.addKeepMainRule(TestClass.class)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
.enableNeverClassInliningAnnotations()
@@ -76,6 +78,7 @@
@NeverClassInline
static class B extends A {
+ @KeepConstantArguments
@NeverInline
public Object m(String arg) {
return System.currentTimeMillis() >= 0 ? arg : null;
@@ -83,6 +86,7 @@
// This bridge cannot be hoisted to A, since it targets a method on the enclosing class.
// Hoisting the bridge to A would lead to a NoSuchMethodError.
+ @KeepConstantArguments
@NeverInline
public /*bridge*/ String bridge(Object o) {
return (String) m((String) o);
diff --git a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/PositiveBridgeHoistingTest.java b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/PositiveBridgeHoistingTest.java
index dbdb906..ae77a45 100644
--- a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/PositiveBridgeHoistingTest.java
+++ b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/PositiveBridgeHoistingTest.java
@@ -7,6 +7,7 @@
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
@@ -51,6 +52,7 @@
.setBridge(B5.class.getDeclaredMethod("virtualBridge", Object.class))
.transform())
.addKeepMainRule(TestClass.class)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
@@ -106,6 +108,7 @@
static class A {
+ @KeepConstantArguments
@NeverInline
public Object m(String arg) {
return System.currentTimeMillis() >= 0 ? arg : null;
@@ -122,12 +125,14 @@
// This bridge can be hoisted to A if the invoke-super instruction is rewritten to an
// invoke-virtual instruction.
+ @KeepConstantArguments
@NeverInline
public /*bridge*/ String superBridge(Object o) {
return (String) super.m((String) o);
}
// This bridge can be hoisted to A.
+ @KeepConstantArguments
@NeverInline
public /*bridge*/ String virtualBridge(Object o) {
return (String) m((String) o);
@@ -139,12 +144,14 @@
static class B2 extends A {
// By hoisting B1.superBridge() to A this method bridge redundant.
+ @KeepConstantArguments
@NeverInline
public /*bridge*/ String superBridge(Object o) {
return (String) super.m((String) o);
}
// By hoisting B1.virtualBridge() to A this method bridge redundant.
+ @KeepConstantArguments
@NeverInline
public /*bridge*/ String virtualBridge(Object o) {
return (String) m((String) o);
@@ -171,11 +178,13 @@
@NoHorizontalClassMerging
static class B4 extends A {
+ @KeepConstantArguments
@NeverInline
public String superBridge(Object o) {
return System.currentTimeMillis() >= 0 ? ((String) o) : null;
}
+ @KeepConstantArguments
@NeverInline
public String virtualBridge(Object o) {
return System.currentTimeMillis() >= 0 ? ((String) o) : null;
@@ -188,11 +197,13 @@
@NoHorizontalClassMerging
static class B5 extends A {
+ @KeepConstantArguments
@NeverInline
public /*bridge*/ String superBridge(Object o) {
return (String) super.m2((String) o);
}
+ @KeepConstantArguments
@NeverInline
public /*bridge*/ String virtualBridge(Object o) {
return (String) m2((String) o);
diff --git a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/testclasses/BridgeHoistingAccessibilityTestClasses.java b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/testclasses/BridgeHoistingAccessibilityTestClasses.java
index e7d430f..64c19e5 100644
--- a/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/testclasses/BridgeHoistingAccessibilityTestClasses.java
+++ b/src/test/java/com/android/tools/r8/bridgeremoval/hoisting/testclasses/BridgeHoistingAccessibilityTestClasses.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.bridgeremoval.hoisting.testclasses;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
import com.android.tools.r8.NoVerticalClassMerging;
@@ -33,6 +34,7 @@
@NoVerticalClassMerging
public static class AWithRangedInvoke {
+ @KeepConstantArguments
@NeverInline
public Object m(String arg, int a, int b, int c, int d, int e) {
return System.currentTimeMillis() > 0 ? arg + a + b + c + d + e : null;
diff --git a/src/test/java/com/android/tools/r8/classmerging/StatefulSingletonClassesMergingTest.java b/src/test/java/com/android/tools/r8/classmerging/StatefulSingletonClassesMergingTest.java
index fadf934..3f887af 100644
--- a/src/test/java/com/android/tools/r8/classmerging/StatefulSingletonClassesMergingTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/StatefulSingletonClassesMergingTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.classmerging;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NeverPropagateValue;
@@ -35,6 +36,7 @@
.addKeepMainRule(Main.class)
.addHorizontallyMergedClassesInspector(
inspector -> inspector.assertIsCompleteMergeGroup(A.class, B.class))
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableMemberValuePropagationAnnotations()
.enableNeverClassInliningAnnotations()
@@ -58,6 +60,9 @@
@NeverPropagateValue private final String data;
+ // TODO(b/198758663): With argument propagation the constructors end up not being equivalent,
+ // which prevents merging in the final round of horizontal class merging.
+ @KeepConstantArguments
A(String data) {
this.data = data;
}
@@ -75,6 +80,9 @@
@NeverPropagateValue private final String data;
+ // TODO(b/198758663): With argument propagation the constructors end up not being equivalent,
+ // which prevents merging in the final round of horizontal class merging.
+ @KeepConstantArguments
B(String data) {
this.data = data;
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/NoClassesOrMembersWithAnnotationsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/NoClassesOrMembersWithAnnotationsTest.java
index 3858a1e..667c261 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/NoClassesOrMembersWithAnnotationsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/NoClassesOrMembersWithAnnotationsTest.java
@@ -9,6 +9,7 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.onlyIf;
import static org.hamcrest.MatcherAssert.assertThat;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestParameters;
@@ -52,18 +53,13 @@
} else {
inspector.assertIsCompleteMergeGroup(A.class, B.class, C.class);
}
+ inspector.assertNoOtherClassesMerged();
})
+ .enableConstantArgumentAnnotations()
.enableNeverClassInliningAnnotations()
.enableInliningAnnotations()
.setMinApi(parameters.getApiLevel())
- .run(parameters.getRuntime(), Main.class)
- .applyIf(
- enableProguardCompatibilityMode,
- result ->
- result.assertSuccessWithOutputLines(
- "a", "b", "c", "foo", "null", "annotation 2", "annotation 1", "annotation 2"),
- result ->
- result.assertSuccessWithOutputLines("a", "b", "c", "foo", "null", "annotation 2"))
+ .compile()
.inspect(
codeInspector -> {
assertThat(codeInspector.clazz(TypeAnnotation.class), isPresent());
@@ -73,7 +69,15 @@
codeInspector.clazz(B.class),
onlyIf(enableProguardCompatibilityMode, isPresent()));
assertThat(codeInspector.clazz(C.class), isAbsent());
- });
+ })
+ .run(parameters.getRuntime(), Main.class)
+ .applyIf(
+ enableProguardCompatibilityMode,
+ result ->
+ result.assertSuccessWithOutputLines(
+ "a", "b", "c", "foo", "null", "annotation 2", "annotation 1", "annotation 2"),
+ result ->
+ result.assertSuccessWithOutputLines("a", "b", "c", "foo", "null", "annotation 2"));
}
@Retention(RetentionPolicy.RUNTIME)
@@ -114,6 +118,7 @@
}
static class Main {
+ @KeepConstantArguments
@NeverInline
public static void foo(TypeAnnotation annotation) {
System.out.println(annotation);
@@ -124,7 +129,7 @@
System.out.println(annotation.toString().replaceFirst(".*@.*", "annotation 2"));
}
- public static void main(String[] args) throws NoSuchMethodException {
+ public static void main(String[] args) {
A a = new A();
B b = new B("b");
C c = new C("c");
diff --git a/src/test/java/com/android/tools/r8/compatproguard/reflection/ReflectionTest.java b/src/test/java/com/android/tools/r8/compatproguard/reflection/ReflectionTest.java
index aab82f0..352186b 100644
--- a/src/test/java/com/android/tools/r8/compatproguard/reflection/ReflectionTest.java
+++ b/src/test/java/com/android/tools/r8/compatproguard/reflection/ReflectionTest.java
@@ -8,6 +8,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
@@ -156,6 +157,7 @@
nonConstArraySize(0);
}
+ @KeepConstantArguments
@NeverInline
static void nonConstArraySize(int argumentTypesSize) {
try {
@@ -485,28 +487,23 @@
@Test
public void testNonConstArraySize() throws Exception {
- Class<?> mainClass = MainNonConstArraySize.class;
- R8Command.Builder builder =
- ToolHelper.prepareR8CommandBuilder(
- readClasses(A.class, mainClass, NeverInline.class), emptyConsumer(backend))
- .addLibraryFiles(runtimeJar(backend));
- builder.addProguardConfiguration(
- ImmutableList.of(keepMainProguardConfigurationWithInliningAnnotation(mainClass)),
- Origin.unknown());
- ToolHelper.allowTestProguardOptions(builder);
- AndroidApp output = ToolHelper.runR8(builder.build());
- CodeInspector inspector = new CodeInspector(output);
-
- assertThat(
- inspector.clazz(A.class).method("void", "method0", ImmutableList.of()),
- isPresentAndRenamed());
-
- // The reference run on the Java VM will succeed, whereas the run on the R8 output will fail
- // as in this test we fail to recognize the reflective call. To compare the output of the
- // successful reference run append "java.lang.NoSuchMethodException" to it.
- assertEquals(
- runOnJava(mainClass) + "java.lang.NoSuchMethodException",
- runOnVM(output, mainClass, backend));
+ testForR8(backend)
+ .addProgramClasses(MainNonConstArraySize.class, A.class)
+ .addKeepMainRule(MainNonConstArraySize.class)
+ .enableConstantArgumentAnnotations()
+ .enableInliningAnnotations()
+ .run(MainNonConstArraySize.class)
+ .inspect(
+ inspector -> {
+ assertThat(
+ inspector.clazz(A.class).method("void", "method0", ImmutableList.of()),
+ isPresentAndRenamed());
+ })
+ // The reference run on the Java VM will succeed, whereas the run on the R8 output will fail
+ // as in this test we fail to recognize the reflective call. To compare the output of the
+ // successful reference run append "java.lang.NoSuchMethodException" to it.
+ .assertSuccessWithOutput(
+ runOnJava(MainNonConstArraySize.class) + "java.lang.NoSuchMethodException");
}
@Test
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/JavaUtilFunctionTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/JavaUtilFunctionTest.java
index 0ac3687..2e0481d 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/JavaUtilFunctionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/JavaUtilFunctionTest.java
@@ -8,6 +8,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
@@ -89,6 +90,7 @@
.addKeepMainRule(TestClass.class)
.addInnerClasses(JavaUtilFunctionTest.class)
.setMinApi(parameters.getApiLevel())
+ .enableConstantArgumentAnnotations()
.enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
.compile()
.inspect(this::checkRewrittenArguments)
@@ -103,6 +105,7 @@
static class TestClass {
+ @KeepConstantArguments
@NeverInline
private static String applyFunction(Function<String, String> f) {
return f.apply("Hello, world");
diff --git a/src/test/java/com/android/tools/r8/enumunboxing/VirtualMethodOverrideEnumUnboxingTest.java b/src/test/java/com/android/tools/r8/enumunboxing/VirtualMethodOverrideEnumUnboxingTest.java
index 4c69310..093f902 100644
--- a/src/test/java/com/android/tools/r8/enumunboxing/VirtualMethodOverrideEnumUnboxingTest.java
+++ b/src/test/java/com/android/tools/r8/enumunboxing/VirtualMethodOverrideEnumUnboxingTest.java
@@ -8,6 +8,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoVerticalClassMerging;
@@ -45,6 +46,7 @@
.addInnerClasses(getClass())
.addKeepMainRule(TestClass.class)
.addKeepRules(enumKeepRules.getKeepRules())
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableNoVerticalClassMergingAnnotations()
@@ -89,11 +91,13 @@
@NeverClassInline
static class B extends A {
+ @KeepConstantArguments
@NeverInline
void m(int x, MyEnum y) {
System.out.println("B.m(" + x + " : int, " + y.toString() + " : MyEnum)");
}
+ @KeepConstantArguments
@NeverInline
@Override
void m(MyEnum x, int y) {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/callsites/WithStaticizerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/callsites/WithStaticizerTest.java
index 3c7307c..f392b1d 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/callsites/WithStaticizerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/callsites/WithStaticizerTest.java
@@ -4,9 +4,9 @@
package com.android.tools.r8.ir.optimize.callsites;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertTrue;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/ClassInlinerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/ClassInlinerTest.java
index 9cb52da..cb494cb 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/ClassInlinerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/ClassInlinerTest.java
@@ -240,7 +240,7 @@
SingleTestRunResult<?> result =
testForR8(parameters.getBackend())
.addProgramClasses(classes)
- .enableProguardTestOptions()
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
.addKeepMainRule(main)
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/invalidroot/InvalidRootsTestClass.java b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/invalidroot/InvalidRootsTestClass.java
index 2b29cea..d9785fe 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/classinliner/invalidroot/InvalidRootsTestClass.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/classinliner/invalidroot/InvalidRootsTestClass.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.ir.optimize.classinliner.invalidroot;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
@@ -72,6 +73,7 @@
}
}
+ @KeepConstantArguments
private void neverReturnsNormallyExtra(String prefix, NeverReturnsNormally a) {
throw new RuntimeException("neverReturnsNormallyExtra(" +
prefix + ", " + (a == null ? "null" : a.foo()) + "): " + next());
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/NopInliningConstraintTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/NopInliningConstraintTest.java
index 3295203..dcc572b 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/NopInliningConstraintTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/NopInliningConstraintTest.java
@@ -40,6 +40,8 @@
.addKeepMainRule(Main.class)
.enableAlwaysInliningAnnotations()
.enableInliningAnnotations()
+ // TODO(b/173398086): uniqueMethodWithName() does not work with argument removal.
+ .noMinification()
.setMinApi(parameters.getApiLevel())
.compile()
.inspect(
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SimpleIfNullOrNotNullInliningTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SimpleIfNullOrNotNullInliningTest.java
index c5073c5..f75c4c8 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SimpleIfNullOrNotNullInliningTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SimpleIfNullOrNotNullInliningTest.java
@@ -10,6 +10,7 @@
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverSingleCallerInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -51,6 +52,7 @@
.addProgramClasses(mainClass, TestMethods.class)
.addKeepMainRule(mainClass)
.apply(this::configure)
+ .enableConstantArgumentAnnotations()
.enableNeverSingleCallerInlineAnnotations()
.compile()
.inspect(this::inspect)
@@ -116,6 +118,7 @@
static class TestMethods {
+ @KeepConstantArguments
@NeverSingleCallerInline
static void simpleIfNullTest(Object o) {
if (o == null) {
@@ -135,6 +138,7 @@
System.out.println("!");
}
+ @KeepConstantArguments
@NeverSingleCallerInline
static void simpleIfBothNullTest(Object o1, Object o2) {
if (o1 == null && o2 == null) {
@@ -154,6 +158,7 @@
System.out.println("!");
}
+ @KeepConstantArguments
@NeverSingleCallerInline
static void simpleIfNotNullTest(Object o) {
if (o != null) {
@@ -173,6 +178,7 @@
System.out.println("!");
}
+ @KeepConstantArguments
@NeverSingleCallerInline
static void simpleIfBothNotNullTest(Object o1, Object o2) {
if (o1 != null && o2 != null) {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SimpleIfTrueOrFalseInliningTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SimpleIfTrueOrFalseInliningTest.java
index b7a7186..180b971 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SimpleIfTrueOrFalseInliningTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/conditionalsimpleinlining/SimpleIfTrueOrFalseInliningTest.java
@@ -10,6 +10,7 @@
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverSingleCallerInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -51,6 +52,7 @@
.addProgramClasses(mainClass, TestMethods.class)
.addKeepMainRule(mainClass)
.apply(this::configure)
+ .enableConstantArgumentAnnotations()
.enableNeverSingleCallerInlineAnnotations()
.compile()
.inspect(this::inspect)
@@ -114,6 +116,7 @@
static class TestMethods {
+ @KeepConstantArguments
@NeverSingleCallerInline
static void simpleIfTrueTest(boolean b) {
if (b) {
@@ -133,6 +136,7 @@
System.out.println("!");
}
+ @KeepConstantArguments
@NeverSingleCallerInline
static void simpleIfBothTrueTest(boolean b1, boolean b2) {
if (b1 && b2) {
@@ -152,6 +156,7 @@
System.out.println("!");
}
+ @KeepConstantArguments
@NeverSingleCallerInline
static void simpleIfFalseTest(boolean b) {
if (!b) {
@@ -171,6 +176,7 @@
System.out.println("!");
}
+ @KeepConstantArguments
@NeverSingleCallerInline
static void simpleIfBothFalseTest(boolean b1, boolean b2) {
if (!b1 && !b2) {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/instanceofremoval/InstanceOfRemovalTest.java b/src/test/java/com/android/tools/r8/ir/optimize/instanceofremoval/InstanceOfRemovalTest.java
index 791bbae..09aef4c 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/instanceofremoval/InstanceOfRemovalTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/instanceofremoval/InstanceOfRemovalTest.java
@@ -177,6 +177,6 @@
MethodSubject barMethodSubject = testClass.uniqueMethodWithName("bar");
Iterator<InstructionSubject> barInstructionIterator =
barMethodSubject.iterateInstructions(InstructionSubject::isInstanceOf);
- assertEquals(4, Streams.stream(barInstructionIterator).count());
+ assertEquals(2, Streams.stream(barInstructionIterator).count());
}
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/classtypes/B134462736.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/classtypes/B134462736.java
index 29de662..3a0b304 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/classtypes/B134462736.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/classtypes/B134462736.java
@@ -7,6 +7,7 @@
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -64,6 +65,7 @@
.enableInliningAnnotations()
.addInnerClasses(B134462736.class)
.addKeepMainRule(TestClass.class)
+ .enableConstantArgumentAnnotations()
.setMinApi(parameters.getApiLevel())
.noMinification()
.addOptionsModification(
@@ -78,11 +80,14 @@
}
public static class TestClass {
+
+ @KeepConstantArguments
@NeverInline
public void consumer(String arg1, String arg2) {
System.out.println(arg1 + " " + arg2);
}
+ @KeepConstantArguments
@NeverInline
public void method1(StringBuilder builder, String arg1, String arg2) {
builder.append(arg1);
@@ -90,6 +95,7 @@
consumer(builder.toString(), null);
}
+ @KeepConstantArguments
@NeverInline
public void method2(StringBuilder builder, String arg1, String arg2) {
builder.append(arg1);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/primitivetypes/PrimitiveTypesTest.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/primitivetypes/PrimitiveTypesTest.java
index e384d9b..8cc3b8c 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/primitivetypes/PrimitiveTypesTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/outliner/primitivetypes/PrimitiveTypesTest.java
@@ -5,20 +5,23 @@
package com.android.tools.r8.ir.optimize.outliner.primitivetypes;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static junit.framework.TestCase.assertEquals;
import static org.hamcrest.MatcherAssert.assertThat;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
+import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.CodeMatchers;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
+import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -26,18 +29,30 @@
@RunWith(Parameterized.class)
public class PrimitiveTypesTest extends TestBase {
+ private final boolean enableArgumentPropagation;
private final TestParameters parameters;
- @Parameterized.Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
+ @Parameterized.Parameters(name = "{1}, argument propagation: {0}")
+ public static List<Object[]> data() {
+ return buildParameters(
+ BooleanUtils.values(), getTestParameters().withAllRuntimesAndApiLevels().build());
}
- public PrimitiveTypesTest(TestParameters parameters) {
+ public PrimitiveTypesTest(boolean keepConstantArguments, TestParameters parameters) {
+ this.enableArgumentPropagation = keepConstantArguments;
this.parameters = parameters;
}
private void validateOutlining(CodeInspector inspector, Class<?> testClass, String argumentType) {
+ boolean isStringBuilderOptimized =
+ enableArgumentPropagation
+ && parameters.isDexRuntime()
+ && (argumentType.equals("char") || argumentType.equals("boolean"));
+ if (isStringBuilderOptimized) {
+ assertEquals(1, inspector.allClasses().size());
+ return;
+ }
+
ClassSubject outlineClass =
inspector.clazz(SyntheticItemsTestUtils.syntheticOutlineClass(testClass, 0));
MethodSubject outline0Method =
@@ -56,6 +71,8 @@
public void runTest(Class<?> testClass, String argumentType, String expectedOutput)
throws Exception {
testForR8(parameters.getBackend())
+ .addConstantArgumentAnnotations()
+ .enableConstantArgumentAnnotations(!enableArgumentPropagation)
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.addProgramClasses(testClass)
@@ -120,6 +137,7 @@
static class TestClassBoolean {
+ @KeepConstantArguments
@NeverInline
public static String method1(boolean b) {
StringBuilder sb = new StringBuilder();
@@ -128,6 +146,7 @@
return sb.toString();
}
+ @KeepConstantArguments
@NeverInline
public static String method2(boolean b) {
StringBuilder sb = new StringBuilder();
@@ -144,6 +163,7 @@
static class TestClassByte {
+ @KeepConstantArguments
@NeverInline
public static String method1(byte b) {
MyStringBuilder sb = new MyStringBuilder();
@@ -152,6 +172,7 @@
return sb.toString();
}
+ @KeepConstantArguments
@NeverInline
public static String method2(byte b) {
MyStringBuilder sb = new MyStringBuilder();
@@ -168,6 +189,7 @@
static class TestClassShort {
+ @KeepConstantArguments
@NeverInline
public static String method1(short s) {
MyStringBuilder sb = new MyStringBuilder();
@@ -176,6 +198,7 @@
return sb.toString();
}
+ @KeepConstantArguments
@NeverInline
public static String method2(short s) {
MyStringBuilder sb = new MyStringBuilder();
@@ -192,6 +215,7 @@
static class TestClassChar {
+ @KeepConstantArguments
@NeverInline
public static String method1(char c) {
StringBuilder sb = new StringBuilder();
@@ -200,6 +224,7 @@
return sb.toString();
}
+ @KeepConstantArguments
@NeverInline
public static String method2(char c) {
StringBuilder sb = new StringBuilder();
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
index 5a60806..a1b6f08 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizerTest.java
@@ -410,6 +410,7 @@
R8TestRunResult result =
testForR8(parameters.getBackend())
.addProgramClasses(classes)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.addKeepMainRule(main)
.allowAccessModification()
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/dualcallinline/Candidate.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/dualcallinline/Candidate.java
index 9ccd630..4733ab3 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/dualcallinline/Candidate.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/dualcallinline/Candidate.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.ir.optimize.staticizer.dualcallinline;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
public class Candidate {
@@ -12,6 +13,7 @@
return bar("Candidate::foo()");
}
+ @KeepConstantArguments
@NeverInline
public String bar(String other) {
return "Candidate::bar(" + other + ")";
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/string/StringIsEmptyTest.java b/src/test/java/com/android/tools/r8/ir/optimize/string/StringIsEmptyTest.java
index 5c9c9a3..6c47b03 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/string/StringIsEmptyTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/string/StringIsEmptyTest.java
@@ -58,7 +58,6 @@
// This test wants to check if compile-time computation is not applied to non-null,
// non-constant value. In a simple test setting, call-site optimization knows the argument is
// always a non-null, specific constant, but that is beyond the scope of this test.
- assert !options.callSiteOptimizationOptions().isConstantPropagationEnabled();
}
private void test(SingleTestRunResult result, int expectedStringIsEmptyCount) throws Exception {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/ParameterRewritingTest.java b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/ParameterRewritingTest.java
index 0125189..ee595ce 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/ParameterRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/ParameterRewritingTest.java
@@ -11,7 +11,8 @@
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -25,15 +26,15 @@
@RunWith(Parameterized.class)
public class ParameterRewritingTest extends TestBase {
- private final Backend backend;
+ private final TestParameters parameters;
- @Parameters(name = "Backend: {0}")
- public static Backend[] data() {
- return ToolHelper.getBackends();
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
}
- public ParameterRewritingTest(Backend backend) {
- this.backend = backend;
+ public ParameterRewritingTest(TestParameters parameters) {
+ this.parameters = parameters;
}
@Test
@@ -49,14 +50,15 @@
testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expected);
CodeInspector inspector =
- testForR8(backend)
+ testForR8(parameters.getBackend())
.addInnerClasses(ParameterRewritingTest.class)
.addKeepMainRule(TestClass.class)
.enableInliningAnnotations()
.enableNoHorizontalClassMergingAnnotations()
.addOptionsModification(options -> options.enableClassInlining = false)
.noMinification()
- .run(TestClass.class)
+ .setMinApi(parameters.getApiLevel())
+ .run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(expected)
.inspector();
@@ -64,7 +66,7 @@
MethodSubject createStaticMethodSubject =
factoryClassSubject.uniqueMethodWithName("createStatic");
assertThat(createStaticMethodSubject, isPresent());
- assertEquals(1, createStaticMethodSubject.getMethod().getReference().proto.parameters.size());
+ assertEquals(1, createStaticMethodSubject.getMethod().getParameters().size());
for (int i = 1; i <= 3; ++i) {
String createStaticWithUnusedMethodName = "createStaticWithUnused" + i;
@@ -73,8 +75,8 @@
assertThat(createStaticWithUnusedMethodSubject, isPresent());
DexMethod method = createStaticWithUnusedMethodSubject.getMethod().getReference();
- assertEquals(1, method.proto.parameters.size());
- assertEquals("java.lang.String", method.proto.parameters.toString());
+ assertEquals(1, method.getParameters().size());
+ assertEquals("java.lang.String", method.getParameters().toString());
}
MethodSubject createStaticWithUnusedMethodSubject =
@@ -82,9 +84,9 @@
assertThat(createStaticWithUnusedMethodSubject, isPresent());
DexMethod method = createStaticWithUnusedMethodSubject.getMethod().getReference();
- assertEquals(3, method.proto.parameters.size());
+ assertEquals(3, method.getParameters().size());
assertEquals(
- "java.lang.String java.lang.String java.lang.String", method.proto.parameters.toString());
+ "java.lang.String java.lang.String java.lang.String", method.getParameters().toString());
assertThat(inspector.clazz(Uninstantiated.class), not(isPresent()));
}
@@ -92,26 +94,39 @@
static class TestClass {
public static void main(String[] args) {
- Object obj1 = Factory.createStatic(null, "Factory.createStatic()");
+ Object obj1 = Factory.createStatic(null, asNonConstantString("Factory.createStatic()"));
System.out.println(" -> " + obj1);
Object obj2 =
- Factory.createStaticWithUnused1(new Object(), null, "Factory.createStaticWithUnused1()");
+ Factory.createStaticWithUnused1(
+ new Object(), null, asNonConstantString("Factory.createStaticWithUnused1()"));
System.out.println(" -> " + obj2);
Object obj3 =
- Factory.createStaticWithUnused2(null, new Object(), "Factory.createStaticWithUnused2()");
+ Factory.createStaticWithUnused2(
+ null, new Object(), asNonConstantString("Factory.createStaticWithUnused2()"));
System.out.println(" -> " + obj3);
Object obj4 =
- Factory.createStaticWithUnused3(null, "Factory.createStaticWithUnused3()", new Object());
+ Factory.createStaticWithUnused3(
+ null, asNonConstantString("Factory.createStaticWithUnused3()"), new Object());
System.out.println(" -> " + obj4);
Object obj5 =
Factory.createStaticWithUnused4(
- "Factory", new Object(), null, ".", new Object(), null, "createStaticWithUnused4()");
+ asNonConstantString("Factory"),
+ new Object(),
+ null,
+ asNonConstantString("."),
+ new Object(),
+ null,
+ asNonConstantString("createStaticWithUnused4()"));
System.out.println(" -> " + obj5);
}
+
+ public static String asNonConstantString(String string) {
+ return System.currentTimeMillis() > 0 ? string : null;
+ }
}
@NoHorizontalClassMerging
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/UninstantiatedAnnotatedArgumentsTest.java b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/UninstantiatedAnnotatedArgumentsTest.java
index 339bbbc..663bcf6 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/UninstantiatedAnnotatedArgumentsTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/UninstantiatedAnnotatedArgumentsTest.java
@@ -158,12 +158,14 @@
static class TestClass {
public static void main(String[] args) {
- testRemoveStaticFromStart(null, "Hello", " world!");
- testRemoveStaticFromMiddle("Hello", null, " world!");
- testRemoveStaticFromEnd("Hello", " world!", null);
- new TestClass().testRemoveVirtualFromStart(null, "Hello", " world!");
- new TestClass().testRemoveVirtualFromMiddle("Hello", null, " world!");
- new TestClass().testRemoveVirtualFromEnd("Hello", " world!", null);
+ String hello = System.currentTimeMillis() > 0 ? "Hello" : null;
+ String world = System.currentTimeMillis() > 0 ? " world!" : null;
+ testRemoveStaticFromStart(null, hello, world);
+ testRemoveStaticFromMiddle(hello, null, world);
+ testRemoveStaticFromEnd(hello, world, null);
+ new TestClass().testRemoveVirtualFromStart(null, hello, world);
+ new TestClass().testRemoveVirtualFromMiddle(hello, null, world);
+ new TestClass().testRemoveVirtualFromEnd(hello, world, null);
}
@KeepConstantArguments
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/PrivateInstanceMethodCollisionTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/PrivateInstanceMethodCollisionTest.java
index b7ddd9e..ed2d01d 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/PrivateInstanceMethodCollisionTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/PrivateInstanceMethodCollisionTest.java
@@ -8,6 +8,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
@@ -60,6 +61,7 @@
testForR8(parameters.getBackend())
.addInnerClasses(PrivateInstanceMethodCollisionTest.class)
.addKeepMainRule(TestClass.class)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.minification(minification)
@@ -109,11 +111,13 @@
@NeverClassInline
static class A {
+ @KeepConstantArguments
@NeverInline
private void foo(String used) {
System.out.println("A#foo(" + used + ")");
}
+ @KeepConstantArguments
@NeverInline
void foo(String used, Object unused) {
System.out.println("A#foo(" + used + ", Object)");
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAnnotatedArgumentsTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAnnotatedArgumentsTest.java
index 7cf6193..2f3e14f 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAnnotatedArgumentsTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedAnnotatedArgumentsTest.java
@@ -8,6 +8,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.KeepUnusedArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
@@ -66,6 +67,7 @@
.addKeepAttributes("RuntimeVisibleParameterAnnotations")
.enableNeverClassInliningAnnotations()
.enableInliningAnnotations()
+ .enableConstantArgumentAnnotations()
.enableUnusedArgumentAnnotations(keepUnusedArguments)
// TODO(b/123060011): Mapping not working in presence of unused argument removal.
.minification(keepUnusedArguments)
@@ -152,6 +154,7 @@
new TestClass().testRemoveVirtualFromEnd("Hello", " world!", null);
}
+ @KeepConstantArguments
@KeepUnusedArguments
@NeverInline
static void testRemoveStaticFromStart(
@@ -159,6 +162,7 @@
System.out.println(used + otherUsed);
}
+ @KeepConstantArguments
@KeepUnusedArguments
@NeverInline
static void testRemoveStaticFromMiddle(
@@ -166,6 +170,7 @@
System.out.println(used + otherUsed);
}
+ @KeepConstantArguments
@KeepUnusedArguments
@NeverInline
static void testRemoveStaticFromEnd(
@@ -173,6 +178,7 @@
System.out.println(used + otherUsed);
}
+ @KeepConstantArguments
@KeepUnusedArguments
@NeverInline
void testRemoveVirtualFromStart(
@@ -180,6 +186,7 @@
System.out.println(used + otherUsed);
}
+ @KeepConstantArguments
@KeepUnusedArguments
@NeverInline
void testRemoveVirtualFromMiddle(
@@ -187,6 +194,7 @@
System.out.println(used + otherUsed);
}
+ @KeepConstantArguments
@KeepUnusedArguments
@NeverInline
void testRemoveVirtualFromEnd(
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionMappingTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionMappingTest.java
index d8a7d6b..7d9a941 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionMappingTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsCollisionMappingTest.java
@@ -10,6 +10,7 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
@@ -50,6 +51,7 @@
.addProgramClasses(Main.class)
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(Main.class)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.addKeepAttributeLineNumberTable()
.run(parameters.getRuntime(), Main.class)
@@ -92,6 +94,7 @@
System.out.println("test with unused");
}
+ @KeepConstantArguments
@NeverInline
public static void test(String used, String unused) {
System.out.println("test with used: " + used);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsDoubleTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsDoubleTest.java
index 95d571d..282371b 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsDoubleTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsDoubleTest.java
@@ -6,7 +6,9 @@
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import java.util.Collection;
import org.junit.Assert;
@@ -27,16 +29,19 @@
}
static class TestClass {
+ @KeepConstantArguments
@NeverInline
public static double a(double a) {
return a;
}
+ @KeepConstantArguments
@NeverInline
public static double a(double a, double b) {
return a;
}
+ @KeepConstantArguments
@NeverInline
public static double a(double a, double b, double c) {
return a;
@@ -50,6 +55,12 @@
}
@Override
+ public void configure(R8FullTestBuilder builder) {
+ super.configure(builder);
+ builder.enableConstantArgumentAnnotations();
+ }
+
+ @Override
public Class<?> getTestClass() {
return TestClass.class;
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsIntTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsIntTest.java
index 06f665d..80309b2 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsIntTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsIntTest.java
@@ -6,7 +6,9 @@
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.google.common.collect.ImmutableSet;
import java.util.Collection;
@@ -31,22 +33,26 @@
static class TestClass {
+ @KeepConstantArguments
@NeverInline
public static int a(int a) {
return a;
}
+ @KeepConstantArguments
@NeverInline
public static int a(int a, int b) {
return a;
}
+ @KeepConstantArguments
@NeverInline
public static int iinc(int a, int b) {
b++;
return a;
}
+ @KeepConstantArguments
@NeverInline
public static int a(int a, int b, int c) {
return a;
@@ -61,6 +67,12 @@
}
@Override
+ public void configure(R8FullTestBuilder builder) {
+ super.configure(builder);
+ builder.enableConstantArgumentAnnotations();
+ }
+
+ @Override
public Class<?> getTestClass() {
return TestClass.class;
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsLongTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsLongTest.java
index 6f44c8d..0dba75b 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsLongTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsLongTest.java
@@ -6,7 +6,9 @@
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import java.util.Collection;
import org.junit.Assert;
@@ -27,16 +29,20 @@
}
static class TestClass {
+
+ @KeepConstantArguments
@NeverInline
public static long a(long a) {
return a;
}
+ @KeepConstantArguments
@NeverInline
public static long a(long a, long b) {
return a;
}
+ @KeepConstantArguments
@NeverInline
public static long a(long a, long b, long c) {
return a;
@@ -50,6 +56,12 @@
}
@Override
+ public void configure(R8FullTestBuilder builder) {
+ super.configure(builder);
+ builder.enableConstantArgumentAnnotations();
+ }
+
+ @Override
public Class<?> getTestClass() {
return TestClass.class;
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsMixedTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsMixedTest.java
index 717adac..dd63e78 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsMixedTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsMixedTest.java
@@ -6,7 +6,9 @@
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import java.util.Collection;
import org.junit.Assert;
@@ -27,6 +29,8 @@
}
static class TestClass {
+
+ @KeepConstantArguments
@NeverInline
public static int a(int a, Object b) {
return a;
@@ -37,6 +41,7 @@
return a;
}
+ @KeepConstantArguments
@NeverInline
public static int a(int a, Object b, int c) {
return c;
@@ -56,6 +61,12 @@
}
@Override
+ public void configure(R8FullTestBuilder builder) {
+ super.configure(builder);
+ builder.enableConstantArgumentAnnotations();
+ }
+
+ @Override
public Class<?> getTestClass() {
return TestClass.class;
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsMixedWidthTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsMixedWidthTest.java
index e10793d..7ed9021 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsMixedWidthTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsMixedWidthTest.java
@@ -6,7 +6,9 @@
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import java.util.Collection;
import org.junit.Assert;
@@ -27,21 +29,26 @@
}
static class TestClass {
+
+ @KeepConstantArguments
@NeverInline
public static int a(int a, long b) {
return a;
}
+ @KeepConstantArguments
@NeverInline
public static long a(long a, int b) {
return a;
}
+ @KeepConstantArguments
@NeverInline
public static int a(int a, long b, int c) {
return c;
}
+ @KeepConstantArguments
@NeverInline
public static long a(long a, int b, long c) {
return c;
@@ -56,6 +63,12 @@
}
@Override
+ public void configure(R8FullTestBuilder builder) {
+ super.configure(builder);
+ builder.enableConstantArgumentAnnotations();
+ }
+
+ @Override
public Class<?> getTestClass() {
return TestClass.class;
}
diff --git a/src/test/java/com/android/tools/r8/jasmin/JasminBuilder.java b/src/test/java/com/android/tools/r8/jasmin/JasminBuilder.java
index 7f41f05..beb87b8 100644
--- a/src/test/java/com/android/tools/r8/jasmin/JasminBuilder.java
+++ b/src/test/java/com/android/tools/r8/jasmin/JasminBuilder.java
@@ -95,6 +95,8 @@
private boolean isInterface = false;
private String access = "public";
+ private final List<String> pendingAnnotations = new ArrayList<>();
+
private ClassBuilder(String name) {
this(name, "java/lang/Object");
}
@@ -124,6 +126,13 @@
return addMethod("public abstract", name, argumentTypes, returnType);
}
+ public void addRuntimeInvisibleAnnotation(String typeName) {
+ pendingAnnotations.add(
+ StringUtils.lines(
+ ".annotation invisible " + DescriptorUtils.javaTypeToDescriptor(typeName),
+ ".end annotation"));
+ }
+
public MethodSignature addFinalMethod(
String name,
List<String> argumentTypes,
@@ -221,6 +230,10 @@
.append(StringUtils.join("", argumentTypes, BraceType.PARENS))
.append(returnType)
.append("\n");
+ if (!pendingAnnotations.isEmpty()) {
+ pendingAnnotations.forEach(builder::append);
+ pendingAnnotations.clear();
+ }
for (String line : lines) {
builder.append(line).append("\n");
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java b/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
index 495eae6..2516b74 100644
--- a/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
+++ b/src/test/java/com/android/tools/r8/kotlin/AbstractR8KotlinTestBase.java
@@ -262,7 +262,7 @@
}
}
- private void checkMethodPresenceInInput(
+ protected void checkMethodPresenceInInput(
String className, MethodSignature methodSignature, boolean isPresent) {
boolean foundMethod = AsmUtils.doesMethodExist(classpath, className,
methodSignature.name, methodSignature.toDescriptor());
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
index 3d872c4..46adea0 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinAccessorTest.java
@@ -14,6 +14,7 @@
import com.android.tools.r8.R8TestBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
@@ -28,7 +29,6 @@
import java.util.Collection;
import java.util.Collections;
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -111,7 +111,7 @@
} else {
assertTrue(fieldSubject.getField().accessFlags.isPrivate());
checkMethodIsKept(outerClass, getterAccessor);
- checkMethodIsKept(outerClass, setterAccessor);
+ checkMethodIsRemoved(outerClass, setterAccessor);
}
});
}
@@ -146,7 +146,7 @@
assertTrue(fieldSubject.getField().accessFlags.isPrivate());
checkMethodIsKept(outerClass, getterAccessor);
- checkMethodIsKept(outerClass, setterAccessor);
+ checkMethodIsRemoved(outerClass, setterAccessor);
}
});
}
@@ -180,7 +180,7 @@
} else {
assertTrue(fieldSubject.getField().accessFlags.isPrivate());
checkMethodIsKept(outerClass, getterAccessor);
- checkMethodIsKept(outerClass, setterAccessor);
+ checkMethodIsRemoved(outerClass, setterAccessor);
}
});
}
@@ -214,7 +214,7 @@
} else {
assertTrue(fieldSubject.getField().accessFlags.isPrivate());
checkMethodIsKept(outerClass, getterAccessor);
- checkMethodIsKept(outerClass, setterAccessor);
+ checkMethodIsRemoved(outerClass, setterAccessor);
}
});
}
@@ -247,7 +247,7 @@
} else {
assertTrue(fieldSubject.getField().accessFlags.isPrivate());
checkMethodIsKept(outerClass, getterAccessor);
- checkMethodIsKept(outerClass, setterAccessor);
+ checkMethodIsRemoved(outerClass, setterAccessor);
}
});
}
@@ -340,7 +340,6 @@
}
@Test
- @Ignore("b/74103342")
public void testAccessorFromPrivate() throws Exception {
TestKotlinCompanionClass testedClass = ACCESSOR_COMPANION_PROPERTY_CLASS;
String mainClass = addMainToClasspath("accessors.AccessorKt",
@@ -348,28 +347,8 @@
runTest("accessors", mainClass)
.inspect(
inspector -> {
- ClassSubject outerClass =
- checkClassIsKept(inspector, testedClass.getOuterClassName());
- ClassSubject companionClass = checkClassIsKept(inspector, testedClass.getClassName());
- String propertyName = "property";
- FieldSubject fieldSubject =
- checkFieldIsKept(outerClass, JAVA_LANG_STRING, propertyName);
- assertTrue(fieldSubject.getField().accessFlags.isStatic());
-
- // We cannot inline the getter because we don't know if NPE is preserved.
- MemberNaming.MethodSignature getter = testedClass.getGetterForProperty(propertyName);
- checkMethodIsKept(companionClass, getter);
-
- // We should always inline the static accessor method.
- MemberNaming.MethodSignature getterAccessor =
- testedClass.getGetterAccessorForProperty(propertyName, AccessorKind.FROM_INNER);
- checkMethodIsRemoved(companionClass, getterAccessor);
-
- if (allowAccessModification) {
- assertTrue(fieldSubject.getField().accessFlags.isPublic());
- } else {
- assertTrue(fieldSubject.getField().accessFlags.isPrivate());
- }
+ checkClassIsRemoved(inspector, testedClass.getOuterClassName());
+ checkClassIsRemoved(inspector, testedClass.getClassName());
});
}
@@ -389,7 +368,6 @@
}
@Test
- @Ignore("b/74103342")
public void testPrivatePropertyAccessorForInnerClassCanBeInlined() throws Exception {
TestKotlinClass testedClass = PROPERTY_ACCESS_FOR_INNER_CLASS;
String mainClass = addMainToClasspath(testedClass.className + "Kt",
@@ -397,6 +375,13 @@
runTest("accessors", mainClass)
.inspect(
inspector -> {
+ if (allowAccessModification
+ && (testParameters.isCfRuntime()
+ || !kotlinParameters.is(KOTLINC_1_5_0, KotlinTargetVersion.JAVA_8))) {
+ checkClassIsRemoved(inspector, testedClass.getClassName());
+ return;
+ }
+
ClassSubject classSubject = checkClassIsKept(inspector, testedClass.getClassName());
String propertyName = "privateProp";
@@ -415,13 +400,12 @@
} else {
assertTrue(fieldSubject.getField().accessFlags.isPrivate());
checkMethodIsKept(classSubject, getterAccessor);
- checkMethodIsKept(classSubject, setterAccessor);
+ checkMethodIsRemoved(classSubject, setterAccessor);
}
});
}
@Test
- @Ignore("b/74103342")
public void testPrivateLateInitPropertyAccessorForInnerClassCanBeInlined() throws Exception {
TestKotlinClass testedClass = PROPERTY_ACCESS_FOR_INNER_CLASS;
String mainClass = addMainToClasspath(testedClass.className + "Kt",
@@ -429,31 +413,15 @@
runTest("accessors", mainClass)
.inspect(
inspector -> {
- ClassSubject classSubject = checkClassIsKept(inspector, testedClass.getClassName());
-
- String propertyName = "privateLateInitProp";
- FieldSubject fieldSubject =
- checkFieldIsKept(classSubject, JAVA_LANG_STRING, propertyName);
- assertFalse(fieldSubject.getField().accessFlags.isStatic());
-
- MemberNaming.MethodSignature getterAccessor =
- testedClass.getGetterAccessorForProperty(propertyName, AccessorKind.FROM_INNER);
- MemberNaming.MethodSignature setterAccessor =
- testedClass.getSetterAccessorForProperty(propertyName, AccessorKind.FROM_INNER);
- if (allowAccessModification) {
- assertTrue(fieldSubject.getField().accessFlags.isPublic());
- checkMethodIsRemoved(classSubject, getterAccessor);
- checkMethodIsRemoved(classSubject, setterAccessor);
+ if (kotlinc.getCompilerVersion() == KOTLINC_1_5_0 && testParameters.isDexRuntime()) {
+ checkClassIsKept(inspector, testedClass.getClassName());
} else {
- assertTrue(fieldSubject.getField().accessFlags.isPrivate());
- checkMethodIsKept(classSubject, getterAccessor);
- checkMethodIsKept(classSubject, setterAccessor);
+ checkClassIsRemoved(inspector, testedClass.getClassName());
}
});
}
@Test
- @Ignore("b/74103342")
public void testAccessorForLambdaIsRemovedWhenNotUsed() throws Exception {
TestKotlinClass testedClass = PROPERTY_ACCESS_FOR_LAMBDA_CLASS;
String mainClass = addMainToClasspath(testedClass.className + "Kt",
@@ -461,21 +429,11 @@
runTest("accessors", mainClass)
.inspect(
inspector -> {
- ClassSubject classSubject = checkClassIsKept(inspector, testedClass.getClassName());
- String propertyName = "property";
-
- MemberNaming.MethodSignature getterAccessor =
- testedClass.getGetterAccessorForProperty(propertyName, AccessorKind.FROM_LAMBDA);
- MemberNaming.MethodSignature setterAccessor =
- testedClass.getSetterAccessorForProperty(propertyName, AccessorKind.FROM_LAMBDA);
-
- checkMethodIsRemoved(classSubject, getterAccessor);
- checkMethodIsRemoved(classSubject, setterAccessor);
+ checkClassIsRemoved(inspector, testedClass.getClassName());
});
}
@Test
- @Ignore("b/74103342")
public void testAccessorForLambdaCanBeInlined() throws Exception {
TestKotlinClass testedClass = PROPERTY_ACCESS_FOR_LAMBDA_CLASS;
String mainClass = addMainToClasspath(testedClass.className + "Kt",
@@ -483,16 +441,25 @@
runTest("accessors", mainClass)
.inspect(
inspector -> {
+ if (allowAccessModification) {
+ checkClassIsRemoved(inspector, testedClass.getClassName());
+ return;
+ }
+
ClassSubject classSubject = checkClassIsKept(inspector, testedClass.getClassName());
String propertyName = "property";
FieldSubject fieldSubject =
checkFieldIsKept(classSubject, JAVA_LANG_STRING, propertyName);
assertFalse(fieldSubject.getField().accessFlags.isStatic());
+ AccessorKind accessorKind =
+ kotlinc.getCompilerVersion() == KOTLINC_1_5_0
+ ? AccessorKind.FROM_INNER
+ : AccessorKind.FROM_LAMBDA;
MemberNaming.MethodSignature getterAccessor =
- testedClass.getGetterAccessorForProperty(propertyName, AccessorKind.FROM_LAMBDA);
+ testedClass.getGetterAccessorForProperty(propertyName, accessorKind);
MemberNaming.MethodSignature setterAccessor =
- testedClass.getSetterAccessorForProperty(propertyName, AccessorKind.FROM_LAMBDA);
+ testedClass.getSetterAccessorForProperty(propertyName, accessorKind);
if (allowAccessModification) {
assertTrue(fieldSubject.getField().accessFlags.isPublic());
checkMethodIsRemoved(classSubject, getterAccessor);
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java
index 5de5dbd..4457386 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinIntrinsicsTest.java
@@ -54,9 +54,7 @@
"intrinsics",
"intrinsics.IntrinsicsKt",
testBuilder ->
- testBuilder
- .addKeepRules(extraRules)
- .noHorizontalClassMerging(Intrinsics.class))
+ testBuilder.addKeepRules(extraRules).noHorizontalClassMerging(Intrinsics.class))
.inspect(
inspector -> {
ClassSubject intrinsicsClass =
@@ -75,8 +73,7 @@
"checkParameterIsNotNull",
"void",
Lists.newArrayList("java.lang.Object", "java.lang.String")),
- // TODO(b/179866251): This is also different on CF
- !allowAccessModification || testParameters.isCfRuntime())
+ !allowAccessModification)
.build());
});
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java b/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
index 65822f7..c605951 100644
--- a/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/R8KotlinPropertiesTest.java
@@ -253,9 +253,7 @@
runTest(
PACKAGE_NAME,
mainClass,
- testBuilder ->
- testBuilder
- .addOptionsModification(disableAggressiveClassOptimizations))
+ testBuilder -> testBuilder.addOptionsModification(disableAggressiveClassOptimizations))
.inspect(
inspector -> {
ClassSubject classSubject =
@@ -272,7 +270,7 @@
} else {
assertTrue(fieldSubject.getField().accessFlags.isPrivate());
checkMethodIsKept(classSubject, getter);
- checkMethodIsKept(classSubject, setter);
+ checkMethodIsRemoved(classSubject, setter);
}
});
}
@@ -650,9 +648,7 @@
runTest(
PACKAGE_NAME,
mainClass,
- testBuilder ->
- testBuilder
- .addOptionsModification(disableAggressiveClassOptimizations))
+ testBuilder -> testBuilder.addOptionsModification(disableAggressiveClassOptimizations))
.inspect(
inspector -> {
ClassSubject objectClass = checkClassIsKept(inspector, testedClass.getClassName());
@@ -671,7 +667,7 @@
checkMethodIsRemoved(objectClass, setter);
} else {
checkMethodIsKept(objectClass, getter);
- checkMethodIsKept(objectClass, setter);
+ checkMethodIsRemoved(objectClass, setter);
}
if (allowAccessModification) {
@@ -724,9 +720,7 @@
runTest(
PACKAGE_NAME,
mainClass,
- testBuilder ->
- testBuilder
- .addOptionsModification(disableAggressiveClassOptimizations))
+ testBuilder -> testBuilder.addOptionsModification(disableAggressiveClassOptimizations))
.inspect(
inspector -> {
ClassSubject objectClass = checkClassIsKept(inspector, testedClass.getClassName());
@@ -746,7 +740,7 @@
checkMethodIsRemoved(objectClass, setter);
} else {
checkMethodIsKept(objectClass, getter);
- checkMethodIsKept(objectClass, setter);
+ checkMethodIsRemoved(objectClass, setter);
}
if (allowAccessModification) {
@@ -765,9 +759,7 @@
runTest(
PACKAGE_NAME,
mainClass,
- testBuilder ->
- testBuilder
- .addOptionsModification(disableAggressiveClassOptimizations))
+ testBuilder -> testBuilder.addOptionsModification(disableAggressiveClassOptimizations))
.inspect(
inspector -> {
ClassSubject objectClass = checkClassIsKept(inspector, testedClass.getClassName());
@@ -787,7 +779,7 @@
checkMethodIsRemoved(objectClass, setter);
} else {
checkMethodIsKept(objectClass, getter);
- checkMethodIsKept(objectClass, setter);
+ checkMethodIsRemoved(objectClass, setter);
}
if (allowAccessModification) {
@@ -896,9 +888,7 @@
runTest(
PACKAGE_NAME,
mainClass,
- testBuilder ->
- testBuilder
- .addOptionsModification(disableAggressiveClassOptimizations))
+ testBuilder -> testBuilder.addOptionsModification(disableAggressiveClassOptimizations))
.inspect(
inspector -> {
ClassSubject objectClass = checkClassIsKept(inspector, testedClass.getClassName());
@@ -916,7 +906,7 @@
} else {
assertTrue(fieldSubject.getField().accessFlags.isPrivate());
checkMethodIsKept(objectClass, getter);
- checkMethodIsKept(objectClass, setter);
+ checkMethodIsRemoved(objectClass, setter);
}
});
}
diff --git a/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java b/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java
index e83626b..091a8b4 100644
--- a/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/SimplifyIfNotNullKotlinTest.java
@@ -11,6 +11,7 @@
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
@@ -47,7 +48,13 @@
ImmutableList.of("java.util.Collection", STRING, STRING, "java.lang.Integer"));
final String mainClassName = ex1.getClassName();
- final String extraRules = neverInlineMethod(mainClassName, testMethodSignature);
+ final String extraRules =
+ StringUtils.lines(
+ neverInlineMethod(mainClassName, testMethodSignature),
+ // TODO(b/173398086): uniqueMethodWithName() does not work with argument removal.
+ "-keepclassmembers,allowoptimization,allowshrinking class non_null.Example1Kt {",
+ " *** forMakeAndModel(...);",
+ "}");
runTest(
FOLDER,
mainClassName,
@@ -56,7 +63,11 @@
inspector -> {
ClassSubject clazz = checkClassIsKept(inspector, ex1.getClassName());
- MethodSubject testMethod = checkMethodIsKept(clazz, testMethodSignature);
+ // Verify forMakeAndModel(...) is present in the input.
+ checkMethodPresenceInInput(clazz.getOriginalName(), testMethodSignature, true);
+
+ // Find forMakeAndModel(...) after parameter removal.
+ MethodSubject testMethod = clazz.uniqueMethodWithName(testMethodSignature.name);
long ifzCount =
testMethod.streamInstructions().filter(i -> i.isIfEqz() || i.isIfNez()).count();
long paramNullCheckCount =
diff --git a/src/test/java/com/android/tools/r8/naming/EnumMinification.java b/src/test/java/com/android/tools/r8/naming/EnumMinification.java
index aeb142f..3cf01e0 100644
--- a/src/test/java/com/android/tools/r8/naming/EnumMinification.java
+++ b/src/test/java/com/android/tools/r8/naming/EnumMinification.java
@@ -102,7 +102,7 @@
class Main {
public static void main(String[] args) {
- Enum e = Enum.valueOf("VALUE1");
+ Enum e = Enum.valueOf(System.currentTimeMillis() > 0 ? "VALUE1" : null);
System.out.print(e);
}
}
diff --git a/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java b/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
index 3c52044..c129553 100644
--- a/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
+++ b/src/test/java/com/android/tools/r8/naming/KotlinIntrinsicsIdentifierTest.java
@@ -97,7 +97,12 @@
getKotlinAnnotationJar(kotlinc))
.addProgramFiles(getJavaJarFile(FOLDER))
.addKeepMainRule(mainClassName)
+ .addKeepRules(
+ "-keepconstantarguments class kotlin.jvm.internal.Intrinsics {",
+ " *** checkParameterIsNotNull(...);",
+ "}")
.allowDiagnosticWarningMessages()
+ .enableProguardTestOptions()
.minification(minification)
.compile()
.assertAllWarningMessagesMatch(
@@ -158,7 +163,10 @@
"-neverclassinline class **." + targetClassName,
"-" + NoVerticalClassMergingRule.RULE_NAME + " class **." + targetClassName,
"-" + NoHorizontalClassMergingRule.RULE_NAME + " class **." + targetClassName,
- "-neverinline class **." + targetClassName + " { <methods>; }"))
+ "-neverinline class **." + targetClassName + " { <methods>; }",
+ "-keepconstantarguments class kotlin.jvm.internal.Intrinsics {",
+ " *** checkParameterIsNotNull(...);",
+ "}"))
.allowDiagnosticWarningMessages()
.minification(minification)
.compile()
diff --git a/src/test/java/com/android/tools/r8/naming/overloadaggressively/ValidNameConflictTest.java b/src/test/java/com/android/tools/r8/naming/overloadaggressively/ValidNameConflictTest.java
index 3d9645d..6c1175c 100644
--- a/src/test/java/com/android/tools/r8/naming/overloadaggressively/ValidNameConflictTest.java
+++ b/src/test/java/com/android/tools/r8/naming/overloadaggressively/ValidNameConflictTest.java
@@ -444,10 +444,12 @@
ProcessResult javaOutput = runOnJavaNoVerifyRaw(builder, CLASS_NAME);
assertEquals(0, javaOutput.exitCode);
- List<String> pgConfigs = ImmutableList.of(
- keepMainProguardConfiguration(CLASS_NAME),
- "-overloadaggressively",
- "-dontshrink");
+ List<String> pgConfigs =
+ ImmutableList.of(
+ keepMainProguardConfiguration(CLASS_NAME),
+ "-overloadaggressively",
+ "-dontoptimize",
+ "-dontshrink");
AndroidApp app = compileWithR8(builder, pgConfigs, null, backend);
CodeInspector codeInspector = new CodeInspector(app);
diff --git a/src/test/java/com/android/tools/r8/regress/b165825758/Regress165825758Test.java b/src/test/java/com/android/tools/r8/regress/b165825758/Regress165825758Test.java
index bf95231..41d6a49 100644
--- a/src/test/java/com/android/tools/r8/regress/b165825758/Regress165825758Test.java
+++ b/src/test/java/com/android/tools/r8/regress/b165825758/Regress165825758Test.java
@@ -9,6 +9,7 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.NeverReprocessMethod;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
@@ -35,7 +36,7 @@
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimes().withAllApiLevels().build();
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
}
public Regress165825758Test(TestParameters parameters) {
@@ -57,6 +58,7 @@
.addInnerClasses(Regress165825758Test.class)
.addKeepMainRule(TestClass.class)
.addKeepClassRules(A.class)
+ .enableNeverReprocessMethodAnnotations()
.setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), TestClass.class)
.assertSuccessWithOutput(EXPECTED)
@@ -99,6 +101,7 @@
static class A {
@NeverInline
+ @NeverReprocessMethod
void synchronizedMethod() {
synchronized (this) {
TestClass.throwNpe();
diff --git a/src/test/java/com/android/tools/r8/repackage/RepackageWithPackagePrivateMethodParameterAnnotationTest.java b/src/test/java/com/android/tools/r8/repackage/RepackageWithPackagePrivateMethodParameterAnnotationTest.java
index d9833ae..8c754e5 100644
--- a/src/test/java/com/android/tools/r8/repackage/RepackageWithPackagePrivateMethodParameterAnnotationTest.java
+++ b/src/test/java/com/android/tools/r8/repackage/RepackageWithPackagePrivateMethodParameterAnnotationTest.java
@@ -8,6 +8,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -36,6 +37,7 @@
.addKeepClassRules(NonPublicKeptAnnotation.class)
.addKeepRuntimeVisibleParameterAnnotations()
.apply(this::configureRepackaging)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.setMinApi(parameters.getApiLevel())
.compile()
@@ -67,6 +69,7 @@
public static class IneligibleForRepackaging {
+ @KeepConstantArguments
@NeverInline
public static void greet(@NonPublicKeptAnnotation String greeting) {
System.out.println(greeting);
diff --git a/src/test/java/com/android/tools/r8/rewrite/enums/EnumOptimizationTest.java b/src/test/java/com/android/tools/r8/rewrite/enums/EnumOptimizationTest.java
index 7733b23..a9574e8 100644
--- a/src/test/java/com/android/tools/r8/rewrite/enums/EnumOptimizationTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/enums/EnumOptimizationTest.java
@@ -57,6 +57,7 @@
testForR8(parameters.getBackend())
.addProgramClassesAndInnerClasses(Ordinals.class)
.addKeepMainRule(Ordinals.class)
+ .enableConstantArgumentAnnotations()
.enableForceInliningAnnotations()
.enableInliningAnnotations()
.enableSideEffectAnnotations()
@@ -106,6 +107,7 @@
testForR8(parameters.getBackend())
.addProgramClassesAndInnerClasses(Names.class)
.addKeepMainRule(Names.class)
+ .enableConstantArgumentAnnotations()
.enableForceInliningAnnotations()
.enableInliningAnnotations()
.enableSideEffectAnnotations()
@@ -152,6 +154,7 @@
testForR8(parameters.getBackend())
.addProgramClassesAndInnerClasses(ToStrings.class)
.addKeepMainRule(ToStrings.class)
+ .enableConstantArgumentAnnotations()
.enableForceInliningAnnotations()
.enableInliningAnnotations()
.enableSideEffectAnnotations()
diff --git a/src/test/java/com/android/tools/r8/rewrite/enums/Names.java b/src/test/java/com/android/tools/r8/rewrite/enums/Names.java
index 5dd5ec0..1c2964c 100644
--- a/src/test/java/com/android/tools/r8/rewrite/enums/Names.java
+++ b/src/test/java/com/android/tools/r8/rewrite/enums/Names.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.AssumeMayHaveSideEffects;
import com.android.tools.r8.ForceInline;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import java.util.concurrent.TimeUnit;
@@ -69,6 +70,7 @@
return Number.DEFAULT.name();
}
+ @KeepConstantArguments
@NeverInline
private static String phi(boolean value) {
Number number = Number.ONE;
diff --git a/src/test/java/com/android/tools/r8/rewrite/enums/Ordinals.java b/src/test/java/com/android/tools/r8/rewrite/enums/Ordinals.java
index e1eee2c..c3fbffc 100644
--- a/src/test/java/com/android/tools/r8/rewrite/enums/Ordinals.java
+++ b/src/test/java/com/android/tools/r8/rewrite/enums/Ordinals.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.AssumeMayHaveSideEffects;
import com.android.tools.r8.ForceInline;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import java.util.concurrent.TimeUnit;
@@ -79,6 +80,7 @@
return Number.DEFAULT.ordinal();
}
+ @KeepConstantArguments
@NeverInline
private static long phi(boolean value) {
Number number = Number.ONE;
diff --git a/src/test/java/com/android/tools/r8/rewrite/enums/ToStrings.java b/src/test/java/com/android/tools/r8/rewrite/enums/ToStrings.java
index 8055344..020f5fd 100644
--- a/src/test/java/com/android/tools/r8/rewrite/enums/ToStrings.java
+++ b/src/test/java/com/android/tools/r8/rewrite/enums/ToStrings.java
@@ -6,6 +6,7 @@
import com.android.tools.r8.AssumeMayHaveSideEffects;
import com.android.tools.r8.ForceInline;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
@@ -106,6 +107,7 @@
return NoToString.DEFAULT.toString();
}
+ @KeepConstantArguments
@NeverInline
private static String phi(boolean value) {
NoToString number = NoToString.ONE;
diff --git a/src/test/java/com/android/tools/r8/rewrite/switches/MaxIntSwitchTest.java b/src/test/java/com/android/tools/r8/rewrite/switches/MaxIntSwitchTest.java
index b32e476..26dcb7a 100644
--- a/src/test/java/com/android/tools/r8/rewrite/switches/MaxIntSwitchTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/switches/MaxIntSwitchTest.java
@@ -7,6 +7,7 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NeverPropagateValue;
import com.android.tools.r8.TestBase;
@@ -104,6 +105,7 @@
testForR8(parameters.getBackend())
.addInnerClasses(this.getClass())
.addKeepMainRule(TestClass.class)
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableMemberValuePropagationAnnotations()
.setMinApi(parameters.getApiLevel())
@@ -125,6 +127,7 @@
"?");
static class TestClass {
+ @KeepConstantArguments
@NeverInline
@NeverPropagateValue
public static void f(int i) {
@@ -143,6 +146,7 @@
}
}
+ @KeepConstantArguments
@NeverInline
@NeverPropagateValue
public static void g(int i) {
@@ -162,6 +166,7 @@
}
}
+ @KeepConstantArguments
@NeverInline
@NeverPropagateValue
public static void h(int i) {
@@ -174,6 +179,7 @@
}
}
+ @KeepConstantArguments
@NeverInline
@NeverPropagateValue
public static void s(String s) {
diff --git a/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java b/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java
index d98725d..6a95824 100644
--- a/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/KeepAnnotatedMemberTest.java
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import static com.android.tools.r8.DiagnosticsMatcher.diagnosticException;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static com.android.tools.r8.utils.codeinspector.Matchers.proguardConfigurationRuleDoesNotMatch;
import static com.android.tools.r8.utils.codeinspector.Matchers.typeVariableNotInScope;
@@ -13,7 +12,6 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
-import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.R8;
import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.TestBase;
@@ -76,8 +74,7 @@
assertThat(method, isPresent());
}
- // TODO(b/159966986): A general keep rule should not cause compiler assertion errors.
- @Test(expected = CompilationFailedException.class)
+ @Test
public void testPresentAnnotation() throws Exception {
testForR8(Backend.CF)
.addProgramFiles(R8_JAR)
@@ -85,10 +82,7 @@
.addDontWarnGoogle()
.addDontWarnJavax()
.addDontWarn("org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement")
- .allowDiagnosticInfoMessages()
- .compileWithExpectedDiagnostics(
- diagnostics -> diagnostics.assertErrorsMatch(diagnosticException(AssertionError.class)))
- .apply(TestBase::verifyAllInfoFromGenericSignatureTypeParameterValidation);
+ .compile();
}
@Test
diff --git a/src/test/java/com/android/tools/r8/shaking/array/DeadArrayLengthTest.java b/src/test/java/com/android/tools/r8/shaking/array/DeadArrayLengthTest.java
index 14259ca..03d5aa6 100644
--- a/src/test/java/com/android/tools/r8/shaking/array/DeadArrayLengthTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/array/DeadArrayLengthTest.java
@@ -31,7 +31,7 @@
@Parameterized.Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimes().build();
+ return getTestParameters().withAllRuntimesAndApiLevels().build();
}
public DeadArrayLengthTest(TestParameters parameters) {
@@ -65,7 +65,7 @@
testForD8()
.release()
.addProgramClasses(MAIN)
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), MAIN)
.assertSuccessWithOutput(EXPECTED_OUTPUT)
.inspect(codeInspector -> inspect(codeInspector, false));
@@ -79,7 +79,7 @@
.enableInliningAnnotations()
.enableMemberValuePropagationAnnotations()
.noMinification()
- .setMinApi(parameters.getRuntime())
+ .setMinApi(parameters.getApiLevel())
.run(parameters.getRuntime(), MAIN)
.assertSuccessWithOutput(EXPECTED_OUTPUT)
.inspect(codeInspector -> inspect(codeInspector, true));
diff --git a/src/test/java/com/android/tools/r8/shaking/attributes/KeepSignatureTest.java b/src/test/java/com/android/tools/r8/shaking/attributes/KeepSignatureTest.java
index 9dfff6e..fdea6ab 100644
--- a/src/test/java/com/android/tools/r8/shaking/attributes/KeepSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/attributes/KeepSignatureTest.java
@@ -9,6 +9,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8TestBuilder;
@@ -80,6 +81,7 @@
ProguardKeepAttributes.INNER_CLASSES,
ProguardKeepAttributes.ENCLOSING_METHOD)
.setMinApi(parameters.getApiLevel())
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.run(parameters.getRuntime(), KeptClass.class)
@@ -137,6 +139,7 @@
public List<P> notKeptField;
+ @KeepConstantArguments
@NeverInline
public List<P> notKeptMethod(P p1, P p2) {
if (notKeptField != null) {
@@ -163,6 +166,7 @@
return (R) keptField;
}
+ @KeepConstantArguments
@NeverInline
@SuppressWarnings("unchecked")
public <R> R notKeptMethod(T t) {
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking2Test.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking2Test.java
index d951404..74232e1 100644
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking2Test.java
+++ b/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking2Test.java
@@ -3,6 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking.examples;
+import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.shaking.TreeShakingTest;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -10,7 +14,6 @@
import com.google.common.collect.ImmutableList;
import java.util.Collections;
import java.util.List;
-import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -41,7 +44,7 @@
@Test
public void testKeeprules() throws Exception {
runTest(
- TreeShaking2Test::shaking2SuperClassIsAbstract,
+ TreeShaking2Test::shaking2SuperClassIsRemoved,
null,
null,
ImmutableList.of("src/test/examples/shaking2/keep-rules.txt"));
@@ -62,16 +65,15 @@
null, null, null, ImmutableList.of("src/test/examples/shaking2/keep-rules-printusage.txt"));
}
- private static void shaking2SuperClassIsAbstract(CodeInspector inspector) {
+ private static void shaking2SuperClassIsRemoved(CodeInspector inspector) {
ClassSubject clazz = inspector.clazz("shaking2.SuperClass");
- Assert.assertTrue(clazz.isAbstract());
- Assert.assertTrue(clazz.method("void", "virtualMethod", Collections.emptyList()).isAbstract());
- Assert.assertTrue(
- clazz
- .method(
- "void",
- "virtualMethod2",
- ImmutableList.of("int", "int", "int", "int", "int", "int", "int", "int"))
- .isAbstract());
+ assertTrue(clazz.isAbstract());
+ assertTrue(clazz.method("void", "virtualMethod", Collections.emptyList()).isAbstract());
+ assertThat(
+ clazz.method(
+ "void",
+ "virtualMethod2",
+ ImmutableList.of("int", "int", "int", "int", "int", "int", "int", "int")),
+ isAbsent());
}
}
diff --git a/src/test/java/com/android/tools/r8/shaking/keepparameternames/KeepParameterNamesTest.java b/src/test/java/com/android/tools/r8/shaking/keepparameternames/KeepParameterNamesTest.java
index 4740853..4f8131d 100644
--- a/src/test/java/com/android/tools/r8/shaking/keepparameternames/KeepParameterNamesTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/keepparameternames/KeepParameterNamesTest.java
@@ -10,6 +10,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import com.android.tools.r8.KeepConstantArguments;
import com.android.tools.r8.KeepUnusedArguments;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
@@ -173,6 +174,7 @@
.addInnerClasses(KeepParameterNamesTest.class)
.addKeepMainRule(TestClass.class)
.addKeepRules("-keep class " + Api.class.getTypeName() + "{ api*(...); }")
+ .enableConstantArgumentAnnotations()
.enableInliningAnnotations()
.enableNeverClassInliningAnnotations()
.enableUnusedArgumentAnnotations()
@@ -209,6 +211,7 @@
"In Api.api2",
"In Api.api3");
testForR8(parameters.getBackend())
+ .enableConstantArgumentAnnotations()
.enableNeverClassInliningAnnotations()
.enableInliningAnnotations()
.enableUnusedArgumentAnnotations()
@@ -253,6 +256,7 @@
}
@NeverInline
+ @KeepConstantArguments
@KeepUnusedArguments
void api1(int parameter1, String parameter2) {
try {
@@ -264,12 +268,14 @@
}
@NeverInline
+ @KeepConstantArguments
@KeepUnusedArguments
void api2(long parameter1, double parameter2) {
System.out.println("In Api.api2");
}
@NeverInline
+ @KeepConstantArguments
@KeepUnusedArguments
void api3(List<String> parameter1, Map<String, Object> parameter2) {
System.out.println("In Api.api3");
diff --git a/src/test/kotlinR8TestResources/unused_singleton/main.kt b/src/test/kotlinR8TestResources/unused_singleton/main.kt
index 213acb1..6c06b8c 100644
--- a/src/test/kotlinR8TestResources/unused_singleton/main.kt
+++ b/src/test/kotlinR8TestResources/unused_singleton/main.kt
@@ -10,6 +10,6 @@
fun provideGreeting() = "Hello"
}
-fun main(args: Array<String>) {
+fun main(args: Array<String>?) {
println(provideGreeting())
}