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();
   }