[ApiModel] Do not inline into unknown api level
Bug: 216314378
Change-Id: Ic524c743ac2e3c9934eece9e80b57bc393a6e923
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
index 089ccce..72ae4c0 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApiLevelUtils.java
@@ -22,6 +22,10 @@
if (caller.getHolderType() == inlinee.getHolderType()) {
return true;
}
+ ComputedApiLevel apiLevelForCode = caller.getDefinition().getApiLevelForCode();
+ if (apiLevelForCode.isUnknownApiLevel()) {
+ return false;
+ }
// For inlining we only measure if the code has invokes into the library.
return caller
.getDefinition()
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelOutlineMethodMissingClassTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelOutlineMethodMissingClassTest.java
index 7e6d2a5..97ee26b 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelOutlineMethodMissingClassTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelOutlineMethodMissingClassTest.java
@@ -97,10 +97,8 @@
.inspect(
inspector -> {
// No need to check further on CF.
- // TODO(b/216314378): If this changes then we will have more classes here at some
- // point.
- assertEquals(3, inspector.allClasses().size());
if (parameters.isCfRuntime()) {
+ assertEquals(3, inspector.allClasses().size());
return;
}
Method testMethod = TestClass.class.getDeclaredMethod("test");
@@ -117,17 +115,17 @@
.findFirst();
assertFalse(synthesizedMissingNotReferenced.isPresent());
verifyThat(inspector, parameters, addedOn23).isNotOutlinedFrom(testMethod);
- // TODO(b/216314378): We should consider if addedOn27 should not be inlined again.
- verifyThat(inspector, parameters, addedOn27).isNotOutlinedFrom(testMethod);
+ verifyThat(inspector, parameters, addedOn27)
+ .isOutlinedFromUntil(testMethod, finalLibraryMethodLevel);
verifyThat(
inspector,
parameters,
LibraryClass.class.getDeclaredMethod("missingAndReferenced"))
.isNotOutlinedFrom(testMethod);
- if (parameters.getApiLevel().isLessThan(AndroidApiLevel.O_MR1)) {
- assertEquals(5, inspector.allClasses().size());
- } else {
+ if (parameters.getApiLevel().isLessThan(finalLibraryMethodLevel)) {
assertEquals(4, inspector.allClasses().size());
+ } else {
+ assertEquals(3, inspector.allClasses().size());
}
});
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/extrasubclasses/AbstractClassAlsoImplementedByMissingClassTest.java b/src/test/java/com/android/tools/r8/ir/optimize/extrasubclasses/AbstractClassAlsoImplementedByMissingClassTest.java
index 65cc34d..b67037d 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/extrasubclasses/AbstractClassAlsoImplementedByMissingClassTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/extrasubclasses/AbstractClassAlsoImplementedByMissingClassTest.java
@@ -72,10 +72,12 @@
ClassSubject bClassSubject = inspector.clazz(B.class);
assertThat(bClassSubject.uniqueMethodWithName("kept"), isPresent());
- // A.notKept() and B.notKept() should not be present, because the only invoke instruction
- // targeting A.notKept() should have been inlined.
+ // A.notKept() should not be present, because the only invoke instruction targeting A.notKept()
+ // should have been inlined.
assertThat(aClassSubject.uniqueMethodWithName("notKept"), not(isPresent()));
- assertThat(bClassSubject.uniqueMethodWithName("notKept"), not(isPresent()));
+ // B.notKept() is present because the caller has an invoke to an unknown method giving it api
+ // level unknown.
+ assertThat(bClassSubject.uniqueMethodWithName("notKept"), isPresent());
}
static class TestClass {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/extrasubclasses/InterfaceAlsoImplementedByMissingClassTest.java b/src/test/java/com/android/tools/r8/ir/optimize/extrasubclasses/InterfaceAlsoImplementedByMissingClassTest.java
index 89586d8..c371a93 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/extrasubclasses/InterfaceAlsoImplementedByMissingClassTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/extrasubclasses/InterfaceAlsoImplementedByMissingClassTest.java
@@ -70,9 +70,11 @@
ClassSubject aClassSubject = inspector.clazz(A.class);
assertThat(aClassSubject.uniqueMethodWithName("kept"), isPresent());
- // I.notKept() and A.notKept() should not be present, because the only invoke instruction
- // targeting I.notKept() should have been inlined.
+ // I.notKept() should not be present, because the only invoke instruction targeting I.notKept()
+ // should have been inlined.
assertThat(iClassSubject.uniqueMethodWithName("notKept"), not(isPresent()));
+ // A.notKept() is present because the caller has an invoke to an unknown method giving it api
+ // level unknown.
assertThat(aClassSubject.uniqueMethodWithName("notKept"), not(isPresent()));
}