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())