Clear annotations if there are missing annotations when permutating
Bug: b/235733922
Change-Id: I7ea4fa7aa34058ef8434f70b3382cc8cea5c1541
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 53ba483..f5b92d1 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -1480,6 +1480,16 @@
}
if (argumentInfoCollection.hasArgumentPermutation()) {
+ // If we have missing parameter annotations we cannot reliably reorder without handling
+ // missing annotations. We could introduce empty annotations to fill in empty spots but the
+ // missing parameters are only bridged in the reflection api for enums or local/anonymous
+ // classes and permuting such method arguments destroys the "invariant" that these are
+ // shifted.
+ // Having a keep on the members will automatically remove the permutation so the developer
+ // can easily recover.
+ if (newNumberOfMissingParameterAnnotations > 0) {
+ return setParameterAnnotations(ParameterAnnotationsList.empty());
+ }
List<DexAnnotationSet> newPermutedParameterAnnotations =
Arrays.asList(new DexAnnotationSet[method.getParameters().size()]);
for (int parameterIndex = newNumberOfMissingParameterAnnotations;
diff --git a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationEnumParameterTest.java b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationEnumParameterTest.java
index 05bc075..53912a8 100644
--- a/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationEnumParameterTest.java
+++ b/src/test/java/com/android/tools/r8/optimize/proto/ProtoNormalizationEnumParameterTest.java
@@ -4,10 +4,6 @@
package com.android.tools.r8.optimize.proto;
-import static org.junit.Assert.assertThrows;
-
-import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.DiagnosticsMatcher;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
@@ -35,21 +31,15 @@
@Test
public void testR8() throws Exception {
- assertThrows(
- CompilationFailedException.class,
- () ->
- testForR8Compat(parameters.getBackend())
- .addInnerClasses(getClass())
- .setMinApi(parameters.getApiLevel())
- .addKeepClassAndMembersRules(Main.class)
- .addKeepClassRules(CustomAnnotation.class)
- .addKeepRuntimeVisibleParameterAnnotations()
- .enableInliningAnnotations()
- // TODO(b/b/235733922): Should not throw an NPE.
- .compileWithExpectedDiagnostics(
- diagnostics ->
- diagnostics.assertErrorThatMatches(
- DiagnosticsMatcher.diagnosticException(NullPointerException.class))));
+ testForR8Compat(parameters.getBackend())
+ .addInnerClasses(getClass())
+ .setMinApi(parameters.getApiLevel())
+ .addKeepClassAndMembersRules(Main.class)
+ .addKeepClassRules(CustomAnnotation.class)
+ .addKeepRuntimeVisibleParameterAnnotations()
+ .enableInliningAnnotations()
+ .run(parameters.getRuntime(), Main.class, "foo", "bar")
+ .assertSuccessWithOutputLines("2foobar", "TEST_1");
}
@Retention(RetentionPolicy.RUNTIME)