Refine api-safe-join to select nearest api safe class
Change-Id: Ie5269c8b5fd5132a7377445b3fa8e55b2d1d2d18
diff --git a/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java b/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java
index 30e2f54..bdc9c67 100644
--- a/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java
+++ b/src/main/java/com/android/tools/r8/graph/DexTypeUtils.java
@@ -61,20 +61,22 @@
public static DexType findApiSafeUpperBound(
AppView<? extends AppInfoWithClassHierarchy> appView, DexType type) {
DexItemFactory factory = appView.dexItemFactory();
- if (type.toBaseType(factory).isPrimitiveType()) {
+ DexType baseType = type.toBaseType(factory);
+ if (baseType.isPrimitiveType()) {
return type;
}
- DexClass clazz = appView.definitionFor(type.isArrayType() ? type.toBaseType(factory) : type);
+ DexClass clazz = appView.definitionFor(baseType);
if (clazz == null) {
assert false : "We should not have found an upper bound if the hierarchy is missing";
return type;
}
if (!clazz.isLibraryClass()
- || AndroidApiLevelUtils.isApiSafeForReference(clazz.asLibraryClass(), appView)) {
+ || AndroidApiLevelUtils.isApiSafeForReference(clazz.asLibraryClass(), appView)
+ || !clazz.hasSuperType()) {
return type;
}
- // Always just return the object type since this is safe for all api versions.
- return factory.objectType;
+ // Return the nearest API safe supertype.
+ return findApiSafeUpperBound(appView, clazz.getSuperType());
}
public static boolean isTypeAccessibleInMethodContext(
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClInitMergeSuperTypeApiLevelTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClInitMergeSuperTypeApiLevelTest.java
index f0de7ae..6584d53 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/ClInitMergeSuperTypeApiLevelTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/ClInitMergeSuperTypeApiLevelTest.java
@@ -21,6 +21,7 @@
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
+import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
@@ -48,7 +49,7 @@
private TypeReference getMergeReferenceForApiLevel() {
return Reference.typeFromTypeName(
- typeName(canUseExecutable() ? Executable.class : Object.class));
+ typeName(canUseExecutable() ? Executable.class : AccessibleObject.class));
}
@Test