VerticalClassMerger should not merge to a target that narrows access
Bug: 149363086
Change-Id: I238c24345c54cf27f69df073f1201ca1266c1eaf
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 864c421..43110c2 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -500,8 +500,14 @@
if (!(method.accessFlags.isPublic() || method.accessFlags.isPrivate())) {
return true;
}
+ // Check if the target is overriding and narrowing the access.
+ if (method.accessFlags.isPublic()) {
+ DexEncodedMethod targetOverride = target.lookupVirtualMethod(method.method);
+ if (targetOverride != null && !targetOverride.accessFlags.isPublic()) {
+ return true;
+ }
+ }
}
-
// Check that all accesses from [source] to classes or members from the current package of
// [source] will continue to work. This is guaranteed if the methods of [source] do not access
// any private or protected classes or members from the current package of [source].
diff --git a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryWithNarrowingTest.java b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryWithNarrowingTest.java
index 1176c1d..2305c93 100644
--- a/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryWithNarrowingTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/packageprivate/PackagePrivateReentryWithNarrowingTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.resolution.packageprivate;
-import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -16,6 +15,7 @@
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRunResult;
import com.android.tools.r8.ToolHelper.DexVm;
+import com.android.tools.r8.graph.AccessFlags;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
@@ -93,19 +93,18 @@
@Test
public void testR8()
throws ExecutionException, CompilationFailedException, IOException, NoSuchMethodException {
- // TODO(b/149363086): Fix test.
testForR8(parameters.getBackend())
.addProgramClasses(A.class, B.class, C.class, Main.class)
.addProgramClassFileData(getDWithPackagePrivateFoo())
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(Main.class)
.run(parameters.getRuntime(), Main.class)
- .assertFailureWithErrorThatMatches(containsString("IllegalAccessError"));
+ .assertSuccessWithOutputLines(EXPECTED);
}
private byte[] getDWithPackagePrivateFoo() throws NoSuchMethodException, IOException {
return transformer(D.class)
- .setAccessFlags(D.class.getDeclaredMethod("bar"), m -> m.unsetPublic())
+ .setAccessFlags(D.class.getDeclaredMethod("bar"), AccessFlags::unsetPublic)
.transform();
}