Do not rebind a super invoke to an abstract library method
Bug: 213581039
Change-Id: I3fa90c9e0e8313fb55c4e4777a1ff7f95f7ea9cc
diff --git a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
index de68c75..32bc033 100644
--- a/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
+++ b/src/main/java/com/android/tools/r8/optimize/MemberRebindingAnalysis.java
@@ -127,6 +127,7 @@
return resolvedMethod.isLibraryMethod()
&& isAccessibleInAllContexts(resolvedMethod, resolutionResult, contexts)
&& !isInvokeSuperToInterfaceMethod(resolvedMethod, invokeType)
+ && !isInvokeSuperToAbstractMethod(resolvedMethod, invokeType)
&& isApiSafeForMemberRebinding(
resolvedMethod.asLibraryMethod(), androidApiLevelCompute, options);
}
@@ -147,6 +148,10 @@
return method.getHolder().isInterface() && invokeType.isSuper();
}
+ private boolean isInvokeSuperToAbstractMethod(DexClassAndMethod method, Type invokeType) {
+ return method.getAccessFlags().isAbstract() && invokeType.isSuper();
+ }
+
public static DexField validMemberRebindingTargetFor(
DexDefinitionSupplier definitions, DexClassAndField field, DexField original) {
if (field.isProgramField()) {
diff --git a/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingInvokeSuperAbstractTest.java b/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingInvokeSuperAbstractTest.java
index c4eb970..24c31c2 100644
--- a/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingInvokeSuperAbstractTest.java
+++ b/src/test/java/com/android/tools/r8/memberrebinding/MemberRebindingInvokeSuperAbstractTest.java
@@ -69,11 +69,10 @@
// We should never rebind this call to LibraryBase::getSystemService since this can
// cause errors when verifying the code on a device where the image has a definition
// but it is abstract. For more information, see b/213581039.
- // TODO(b/213581039): We should not rebind to the abstract method.
assertThat(
getSystemService,
CodeMatchers.invokesMethodWithHolderAndName(
- typeName(LibraryBase.class), "getSystemService"));
+ typeName(LibrarySub.class), "getSystemService"));
})
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLines("LibrarySub::getSystemService");