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)