Mark all annotation interfaces as having unknown subcless hierachy
Fixes: b/378473616
Change-Id: I4cbd87acfbbddda351cc3206a7b7c3fb6e8ac8f8
diff --git a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
index 2ffe096..669e86b 100644
--- a/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
+++ b/src/main/java/com/android/tools/r8/graph/ObjectAllocationInfoCollectionImpl.java
@@ -122,6 +122,16 @@
return clazz.isInterface() && interfacesWithUnknownSubtypeHierarchy.contains(clazz);
}
+ /**
+ * Returns true if the type is an annotation interface which (by design) has an unknown subtype
+ * hierarchy.
+ */
+ public boolean isAnnotationInterfaceWithUnknownSubtypeHierarchy(DexProgramClass iface) {
+ return iface.isInterface()
+ && iface.isAnnotation()
+ && annotationsWithUnknownSubtypeHierarchy.contains(iface);
+ }
+
/** Returns true if the type is an immediate interface of an instantiated lambda. */
@Override
public boolean isImmediateInterfaceOfInstantiatedLambda(DexProgramClass iface) {
@@ -522,6 +532,18 @@
assert !interfacesWithUnknownSubtypeHierarchy.contains(rewrittenClass);
interfacesWithUnknownSubtypeHierarchy.add(rewrittenClass);
}
+ for (DexProgramClass abstractType :
+ objectAllocationInfos.annotationsWithUnknownSubtypeHierarchy) {
+ DexType type = lens.lookupType(abstractType.type, appliedLens);
+ if (type.isPrimitiveType()) {
+ assert false;
+ continue;
+ }
+ DexProgramClass rewrittenClass = asProgramClassOrNull(definitions.definitionFor(type));
+ assert rewrittenClass != null;
+ assert !annotationsWithUnknownSubtypeHierarchy.contains(rewrittenClass);
+ annotationsWithUnknownSubtypeHierarchy.add(rewrittenClass);
+ }
LensCodeRewriterUtils rewriter = new LensCodeRewriterUtils(definitions, lens, appliedLens);
objectAllocationInfos.instantiatedLambdas.forEach(
(iface, lambdas) -> {
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index 022be10..cbba232 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -1156,8 +1156,10 @@
// TODO(b/148769279): Disable lookup single target on lambda's for now.
if (resolvedHolder.isInterface()
&& resolvedHolder.isProgramClass()
- && objectAllocationInfoCollection.isImmediateInterfaceOfInstantiatedLambda(
- resolvedHolder.asProgramClass())) {
+ && (objectAllocationInfoCollection.isImmediateInterfaceOfInstantiatedLambda(
+ resolvedHolder.asProgramClass())
+ || objectAllocationInfoCollection.isAnnotationInterfaceWithUnknownSubtypeHierarchy(
+ resolvedHolder.asProgramClass()))) {
singleTargetLookupCache.addNoSingleTargetToCache(refinedReceiverType, method);
return null;
}
diff --git a/src/test/java/com/android/tools/r8/optimize/ReproduceKT72888Test.java b/src/test/java/com/android/tools/r8/optimize/AnnotationImplementedAndInstantiatedInProgramTest.java
similarity index 93%
rename from src/test/java/com/android/tools/r8/optimize/ReproduceKT72888Test.java
rename to src/test/java/com/android/tools/r8/optimize/AnnotationImplementedAndInstantiatedInProgramTest.java
index a61ef15..83e0029 100644
--- a/src/test/java/com/android/tools/r8/optimize/ReproduceKT72888Test.java
+++ b/src/test/java/com/android/tools/r8/optimize/AnnotationImplementedAndInstantiatedInProgramTest.java
@@ -15,8 +15,9 @@
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
+// This is a reproduction of b/378473616 (extracted from KT-72888)
@RunWith(Parameterized.class)
-public class ReproduceKT72888Test extends TestBase {
+public class AnnotationImplementedAndInstantiatedInProgramTest extends TestBase {
@Parameter(0)
public TestParameters parameters;
@@ -57,7 +58,7 @@
.addKeepRuntimeVisibleAnnotations()
.setMinApi(parameters)
.run(parameters.getRuntime(), TestClass.class)
- .assertFailureWithErrorThatThrows(ClassCastException.class);
+ .assertSuccessWithOutput(EXPECTED_OUTPUT);
}
@Retention(RetentionPolicy.RUNTIME)