Check for accessibility weaking before rebinding in devirtualizer
Bug: 173812804
Change-Id: Ifc3924fb330c281f4c4fedd87dd34c7831b9ccd4
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
index 89681f0..0ed998a 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Devirtualizer.java
@@ -311,7 +311,11 @@
if (newResolutionResult == null
|| newResolutionResult
.isAccessibleForVirtualDispatchFrom(context, appView.appInfo())
- .isPossiblyFalse()) {
+ .isPossiblyFalse()
+ || !newResolutionResult
+ .getResolvedMethod()
+ .getAccessFlags()
+ .isAtLeastAsVisibleAs(resolutionResult.getResolvedMethod().getAccessFlags())) {
return target;
}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/devirtualize/PrivateOverridePublicizerDevirtualizerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/devirtualize/PrivateOverridePublicizerDevirtualizerTest.java
index bef0cd5..86739dc 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/devirtualize/PrivateOverridePublicizerDevirtualizerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/devirtualize/PrivateOverridePublicizerDevirtualizerTest.java
@@ -5,13 +5,11 @@
package com.android.tools.r8.ir.optimize.devirtualize;
import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoVerticalClassMerging;
-import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
@@ -48,33 +46,25 @@
@Test
public void testR8() throws Exception {
- R8TestRunResult runResult =
- testForR8(parameters.getBackend())
- .addInnerClasses(PrivateOverridePublicizerDevirtualizerTest.class)
- .enableInliningAnnotations()
- .enableNoVerticalClassMergingAnnotations()
- .enableNeverClassInliningAnnotations()
- .addKeepMainRule(Main.class)
- .allowAccessModification()
- .noMinification()
- .setMinApi(parameters.getApiLevel())
- .compile()
- .inspect(
- inspector -> {
- ClassSubject classA = inspector.clazz(A.class);
- assertThat(classA, isPresent());
- MethodSubject fooA = classA.uniqueMethodWithName("foo");
- // TODO(b/173812804): This should not be removed.
- assertThat(fooA, not(isPresent()));
- })
- .run(parameters.getRuntime(), Main.class);
- if (parameters.isDexRuntime()) {
- // TODO(b/173812804): This should not fail verification
- runResult.assertFailureWithErrorThatThrows(VerifyError.class);
- } else {
- // TODO(b/173812804): This should have been A::foo, B::foo.
- runResult.assertSuccessWithOutputLines("B::foo", "B::foo");
- }
+ testForR8(parameters.getBackend())
+ .addInnerClasses(PrivateOverridePublicizerDevirtualizerTest.class)
+ .enableInliningAnnotations()
+ .enableNoVerticalClassMergingAnnotations()
+ .enableNeverClassInliningAnnotations()
+ .addKeepMainRule(Main.class)
+ .allowAccessModification()
+ .noMinification()
+ .setMinApi(parameters.getApiLevel())
+ .compile()
+ .inspect(
+ inspector -> {
+ ClassSubject classA = inspector.clazz(A.class);
+ assertThat(classA, isPresent());
+ MethodSubject fooA = classA.uniqueMethodWithName("foo");
+ assertThat(fooA, isPresent());
+ })
+ .run(parameters.getRuntime(), Main.class)
+ .assertSuccessWithOutputLines(EXPECTED);
}
@NeverClassInline