Keep the instantiated class when identifying reflective construction

Fixes: b/387258081
Change-Id: Icad6778099e247c3f045b94f182ab217949a1d28
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 7b78440..77f5fbc 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -1733,6 +1733,18 @@
     return clazz;
   }
 
+  private void traceReflectiveNewInstance(
+      ProgramMethod context, DexProgramClass clazz, ProgramMethod initializer) {
+    assert initializer.getDefinition().isInstanceInitializer();
+    KeepReason reason = KeepReason.reflectiveUseIn(context);
+    traceNewInstance(clazz.getType(), context, InstantiationReason.REFLECTION, reason);
+    markMethodAsTargeted(initializer, reason);
+    markDirectStaticOrConstructorMethodAsLive(initializer, reason);
+    applyMinimumKeepInfoWhenLiveOrTargeted(
+        initializer, KeepMethodInfo.newEmptyJoiner().disallowOptimization());
+    applyMinimumKeepInfoWhenLive(clazz, KeepClassInfo.newEmptyJoiner().disallowOptimization());
+  }
+
   void traceInstanceFieldRead(DexField field, ProgramMethod currentMethod) {
     traceInstanceFieldRead(field, currentMethod, FieldAccessMetadata.DEFAULT);
   }
@@ -5404,12 +5416,7 @@
     }
     ProgramMethod defaultInitializer = clazz.getProgramDefaultInitializer();
     if (defaultInitializer != null) {
-      KeepReason reason = KeepReason.reflectiveUseIn(method);
-      markClassAsInstantiatedWithReason(clazz, reason);
-      markMethodAsTargeted(defaultInitializer, reason);
-      markDirectStaticOrConstructorMethodAsLive(defaultInitializer, reason);
-      applyMinimumKeepInfoWhenLiveOrTargeted(
-          defaultInitializer, KeepMethodInfo.newEmptyJoiner().disallowOptimization());
+      traceReflectiveNewInstance(method, clazz, defaultInitializer);
     }
   }
 
@@ -5525,12 +5532,7 @@
     }
 
     if (initializer != null) {
-      KeepReason reason = KeepReason.reflectiveUseIn(method);
-      markClassAsInstantiatedWithReason(clazz, reason);
-      markMethodAsTargeted(initializer, reason);
-      markDirectStaticOrConstructorMethodAsLive(initializer, reason);
-      applyMinimumKeepInfoWhenLiveOrTargeted(
-          initializer, KeepMethodInfo.newEmptyJoiner().disallowOptimization());
+      traceReflectiveNewInstance(method, clazz, initializer);
     }
   }
 
diff --git a/src/test/java/com/android/tools/r8/shaking/reflection/ReflectiveNewInstanceTest.java b/src/test/java/com/android/tools/r8/shaking/reflection/ReflectiveNewInstanceTest.java
index cdb8f78..8920a35 100644
--- a/src/test/java/com/android/tools/r8/shaking/reflection/ReflectiveNewInstanceTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/reflection/ReflectiveNewInstanceTest.java
@@ -50,7 +50,7 @@
     }
 
     String expectedOutputAfterR8 =
-        StringUtils.lines("Success", "Success", "Success", "Fail", "Fail");
+        StringUtils.lines("Success", "Success", "Success", "Fail", "Fail", "Success", "Success");
 
     GraphInspector inspector =
         testForR8(parameters.getBackend())