Always use invoke-virtual for publicized methods
Change-Id: I18929bdbdd3b065be941a8e497ebe3550e477c56
diff --git a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
index 26e029a..3ad8ed2 100644
--- a/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
+++ b/src/main/java/com/android/tools/r8/cf/code/CfInvoke.java
@@ -351,7 +351,16 @@
private Type invokeTypeForInvokeSpecialToNonInitMethodOnHolder(
AppView<?> appView, CfSourceCode code) {
boolean desugaringEnabled = appView.options().isInterfaceMethodDesugaringEnabled();
- DexEncodedMethod encodedMethod = lookupMethodOnHolder(appView, method);
+ MethodLookupResult lookupResult = appView.graphLens().lookupMethod(method, method, Type.DIRECT);
+ if (lookupResult.getType() == Type.VIRTUAL) {
+ // The method has been publicized. We can't always expect private methods that have been
+ // publicized to be final. For example, if a private method A.m() is publicized, and A is
+ // subsequently merged with a class B, with declares a public non-final method B.m(), then the
+ // horizontal class merger will merge A.m() and B.m() into a new non-final public method.
+ return Type.VIRTUAL;
+ }
+ DexMethod rewrittenMethod = lookupResult.getReference();
+ DexEncodedMethod encodedMethod = lookupMethodOnHolder(appView, rewrittenMethod);
if (encodedMethod == null) {
// The method is not defined on the class, we can use super to target. When desugaring
// default interface methods, it is expected they are targeted with invoke-direct.
@@ -375,12 +384,10 @@
}
private DexEncodedMethod lookupMethodOnHolder(AppView<?> appView, DexMethod method) {
- MethodLookupResult lookupResult = appView.graphLens().lookupMethod(method, method, Type.DIRECT);
- DexMethod rewrittenMethod = lookupResult.getReference();
// Directly lookup the program type for holder. This bypasses lookup order as well as looks
// directly on the application data, which bypasses and indirection or validation.
- DexProgramClass clazz = appView.appInfo().unsafeDirectProgramTypeLookup(rewrittenMethod.holder);
+ DexProgramClass clazz = appView.appInfo().unsafeDirectProgramTypeLookup(method.getHolderType());
assert clazz != null;
- return clazz.lookupMethod(rewrittenMethod);
+ return clazz.lookupMethod(method);
}
}
diff --git a/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java b/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java
index d36cbee..5d2fef0 100644
--- a/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java
+++ b/src/main/java/com/android/tools/r8/optimize/PublicizerLens.java
@@ -60,7 +60,7 @@
assert clazz != null;
DexEncodedMethod actualEncodedTarget = clazz.lookupVirtualMethod(signatureInCurrentWorld);
assert actualEncodedTarget != null;
- assert actualEncodedTarget.isPublicized();
+ assert actualEncodedTarget.isPublic();
return true;
}
diff --git a/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfPublicizedMethodsTest.java b/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfPublicizedMethodsTest.java
index 9b78e3e..5df1264 100644
--- a/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfPublicizedMethodsTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/horizontal/VirtualMethodMergingOfPublicizedMethodsTest.java
@@ -22,9 +22,6 @@
@Test
public void test() throws Exception {
- if (enableHorizontalClassMerging) {
- thrown.expect(CompilationFailedException.class);
- }
testForR8(parameters.getBackend())
.addInnerClasses(getClass())
.addKeepMainRule(TestClass.class)
diff --git a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTest.java b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTest.java
index 3705c2d..b624956 100644
--- a/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/lambda/KotlinLambdaMergingTest.java
@@ -445,6 +445,7 @@
@Test
public void testGenericsSignatureInnerEnclosingKs() throws Exception {
+ expectThrowsWithHorizontalClassMerging();
final String mainClassName = "lambdas_kstyle_generics.MainKt";
runTest(
"lambdas_kstyle_generics",