Mark accessibility changing overrides as targeted.

Bug: b/227302144
Change-Id: I1d765d96234ed21a29460a74d0dfb747c4eca6f0
diff --git a/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java b/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java
index 765fef3..aeab5fe 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClassAndMethod.java
@@ -6,10 +6,9 @@
 
 import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfo;
 import com.android.tools.r8.references.MethodReference;
-import java.util.function.Consumer;
 
 public abstract class DexClassAndMethod extends DexClassAndMember<DexEncodedMethod, DexMethod>
-    implements LookupTarget {
+    implements LookupMethodTarget {
 
   DexClassAndMethod(DexClass holder, DexEncodedMethod method) {
     super(holder, method);
@@ -88,16 +87,6 @@
   }
 
   @Override
-  public boolean isMethodTarget() {
-    return true;
-  }
-
-  @Override
-  public DexClassAndMethod asMethodTarget() {
-    return this;
-  }
-
-  @Override
   public boolean isMethod() {
     return true;
   }
@@ -113,8 +102,7 @@
   }
 
   @Override
-  public void accept(
-      Consumer<DexClassAndMethod> methodConsumer, Consumer<LookupLambdaTarget> lambdaConsumer) {
-    methodConsumer.accept(this);
+  public DexClassAndMethod getTarget() {
+    return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/LookupCompletenessHelper.java b/src/main/java/com/android/tools/r8/graph/LookupCompletenessHelper.java
index 4a99071..504ca65 100644
--- a/src/main/java/com/android/tools/r8/graph/LookupCompletenessHelper.java
+++ b/src/main/java/com/android/tools/r8/graph/LookupCompletenessHelper.java
@@ -38,9 +38,9 @@
     }
   }
 
-  void checkDexClassAndMethod(DexClassAndMethod classAndMethod) {
-    checkClass(classAndMethod.getHolder());
-    checkMethod(classAndMethod.getDefinition());
+  void checkDexClassAndMethod(LookupMethodTarget methodTarget) {
+    checkClass(methodTarget.getHolder());
+    checkMethod(methodTarget.getDefinition());
   }
 
   LookupResultCollectionState computeCollectionState(
diff --git a/src/main/java/com/android/tools/r8/graph/LookupLambdaTarget.java b/src/main/java/com/android/tools/r8/graph/LookupLambdaTarget.java
index 12eeddc..e1209e9 100644
--- a/src/main/java/com/android/tools/r8/graph/LookupLambdaTarget.java
+++ b/src/main/java/com/android/tools/r8/graph/LookupLambdaTarget.java
@@ -30,7 +30,7 @@
 
   @Override
   public void accept(
-      Consumer<DexClassAndMethod> methodConsumer, Consumer<LookupLambdaTarget> lambdaConsumer) {
+      Consumer<LookupMethodTarget> methodConsumer, Consumer<LookupLambdaTarget> lambdaConsumer) {
     lambdaConsumer.accept(this);
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/LookupMethodTarget.java b/src/main/java/com/android/tools/r8/graph/LookupMethodTarget.java
new file mode 100644
index 0000000..b7a6aa0
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/LookupMethodTarget.java
@@ -0,0 +1,33 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.graph;
+
+import java.util.function.Consumer;
+
+public interface LookupMethodTarget extends LookupTarget {
+
+  @Override
+  default boolean isMethodTarget() {
+    return true;
+  }
+
+  @Override
+  default LookupMethodTarget asMethodTarget() {
+    return this;
+  }
+
+  @Override
+  default void accept(
+      Consumer<LookupMethodTarget> methodConsumer, Consumer<LookupLambdaTarget> lambdaConsumer) {
+    methodConsumer.accept(this);
+  }
+
+  DexClass getHolder();
+
+  DexMethod getReference();
+
+  DexEncodedMethod getDefinition();
+
+  DexClassAndMethod getTarget();
+}
diff --git a/src/main/java/com/android/tools/r8/graph/LookupMethodTargetWithAccessOverride.java b/src/main/java/com/android/tools/r8/graph/LookupMethodTargetWithAccessOverride.java
new file mode 100644
index 0000000..d69c5b3
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/LookupMethodTargetWithAccessOverride.java
@@ -0,0 +1,41 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.graph;
+
+public class LookupMethodTargetWithAccessOverride implements LookupMethodTarget {
+
+  private final DexClassAndMethod target;
+  private final DexClassAndMethod accessOverride;
+
+  public LookupMethodTargetWithAccessOverride(
+      DexClassAndMethod target, DexClassAndMethod accessOverride) {
+    this.target = target;
+    this.accessOverride = accessOverride;
+  }
+
+  @Override
+  public DexClassAndMethod getAccessOverride() {
+    return accessOverride;
+  }
+
+  @Override
+  public DexClass getHolder() {
+    return target.getHolder();
+  }
+
+  @Override
+  public DexMethod getReference() {
+    return target.getReference();
+  }
+
+  @Override
+  public DexEncodedMethod getDefinition() {
+    return target.getDefinition();
+  }
+
+  @Override
+  public DexClassAndMethod getTarget() {
+    return target;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/graph/LookupResult.java b/src/main/java/com/android/tools/r8/graph/LookupResult.java
index bc85814..b8bc3c8 100644
--- a/src/main/java/com/android/tools/r8/graph/LookupResult.java
+++ b/src/main/java/com/android/tools/r8/graph/LookupResult.java
@@ -5,10 +5,11 @@
 package com.android.tools.r8.graph;
 
 import com.android.tools.r8.graph.LookupResult.LookupResultSuccess.LookupResultCollectionState;
-import com.android.tools.r8.utils.collections.DexClassAndMethodSet;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.IdentityHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.function.Consumer;
 
 public abstract class LookupResult {
@@ -34,14 +35,14 @@
   }
 
   public abstract void forEach(
-      Consumer<? super DexClassAndMethod> onMethodTarget,
+      Consumer<? super LookupMethodTarget> onMethodTarget,
       Consumer<? super LookupLambdaTarget> onLambdaTarget);
 
   public abstract void forEachFailureDependency(
       Consumer<? super DexEncodedMethod> methodCausingFailureConsumer);
 
   public static LookupResultSuccess createResult(
-      DexClassAndMethodSet methodTargets,
+      Map<DexMethod, LookupMethodTarget> methodTargets,
       List<LookupLambdaTarget> lambdaTargets,
       List<DexEncodedMethod> methodsCausingFailure,
       LookupResultCollectionState state) {
@@ -60,18 +61,18 @@
 
     private static final LookupResultSuccess EMPTY_INSTANCE =
         new LookupResultSuccess(
-            DexClassAndMethodSet.empty(),
+            new IdentityHashMap<>(),
             Collections.emptyList(),
             Collections.emptyList(),
             LookupResultCollectionState.Incomplete);
 
-    private final DexClassAndMethodSet methodTargets;
+    private final Map<DexMethod, LookupMethodTarget> methodTargets;
     private final List<LookupLambdaTarget> lambdaTargets;
     private final List<DexEncodedMethod> methodsCausingFailure;
     private LookupResultCollectionState state;
 
     private LookupResultSuccess(
-        DexClassAndMethodSet methodTargets,
+        Map<DexMethod, LookupMethodTarget> methodTargets,
         List<LookupLambdaTarget> lambdaTargets,
         List<DexEncodedMethod> methodsCausingFailure,
         LookupResultCollectionState state) {
@@ -99,9 +100,9 @@
 
     @Override
     public void forEach(
-        Consumer<? super DexClassAndMethod> onMethodTarget,
+        Consumer<? super LookupMethodTarget> onMethodTarget,
         Consumer<? super LookupLambdaTarget> onLambdaTarget) {
-      methodTargets.forEach(onMethodTarget);
+      methodTargets.forEach((key, value) -> onMethodTarget.accept(value));
       lambdaTargets.forEach(onLambdaTarget);
     }
 
@@ -113,7 +114,7 @@
 
     public boolean contains(DexEncodedMethod method) {
       // Containment of a method in the lookup results only pertains to the method targets.
-      return methodTargets.contains(method);
+      return methodTargets.containsKey(method.getReference());
     }
 
     @Override
@@ -145,7 +146,7 @@
       }
       // TODO(b/150932978): Check lambda targets implementation methods.
       if (methodTargets.size() == 1) {
-        return methodTargets.iterator().next();
+        return methodTargets.values().iterator().next();
       } else if (lambdaTargets.size() == 1) {
         return lambdaTargets.get(0);
       }
@@ -159,13 +160,14 @@
 
     public static class Builder {
 
-      private final DexClassAndMethodSet methodTargets = DexClassAndMethodSet.create();
+      private final Map<DexMethod, LookupMethodTarget> methodTargets = new IdentityHashMap<>();
       private final List<LookupLambdaTarget> lambdaTargets = new ArrayList<>();
       private final List<DexEncodedMethod> methodsCausingFailure = new ArrayList<>();
       private LookupResultCollectionState state;
 
-      public Builder addMethodTarget(DexClassAndMethod methodTarget) {
-        methodTargets.add(methodTarget);
+      public Builder addMethodTarget(LookupMethodTarget methodTarget) {
+        assert methodTarget.isMethodTarget();
+        methodTargets.putIfAbsent(methodTarget.asMethodTarget().getReference(), methodTarget);
         return this;
       }
 
@@ -210,7 +212,7 @@
 
     @Override
     public void forEach(
-        Consumer<? super DexClassAndMethod> onMethodTarget,
+        Consumer<? super LookupMethodTarget> onMethodTarget,
         Consumer<? super LookupLambdaTarget> onLambdaTarget) {
       // Nothing to iterate for a failed lookup.
     }
diff --git a/src/main/java/com/android/tools/r8/graph/LookupTarget.java b/src/main/java/com/android/tools/r8/graph/LookupTarget.java
index cc0d574..4530c0f 100644
--- a/src/main/java/com/android/tools/r8/graph/LookupTarget.java
+++ b/src/main/java/com/android/tools/r8/graph/LookupTarget.java
@@ -14,7 +14,7 @@
     return false;
   }
 
-  default DexClassAndMethod asMethodTarget() {
+  default LookupMethodTarget asMethodTarget() {
     return null;
   }
 
@@ -22,6 +22,10 @@
     return null;
   }
 
+  default DexClassAndMethod getAccessOverride() {
+    return null;
+  }
+
   void accept(
-      Consumer<DexClassAndMethod> methodConsumer, Consumer<LookupLambdaTarget> lambdaConsumer);
+      Consumer<LookupMethodTarget> methodConsumer, Consumer<LookupLambdaTarget> lambdaConsumer);
 }
diff --git a/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java b/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
index 113c31c..49860a7 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodResolutionResult.java
@@ -13,7 +13,6 @@
 import com.android.tools.r8.utils.BooleanBox;
 import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.OptionalBool;
-import com.android.tools.r8.utils.collections.DexClassAndMethodSet;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.function.BiPredicate;
@@ -152,7 +151,7 @@
   public abstract LookupTarget lookupVirtualDispatchTarget(
       InstantiatedObject instance, AppInfoWithClassHierarchy appInfo);
 
-  public abstract DexClassAndMethod lookupVirtualDispatchTarget(
+  public abstract LookupMethodTarget lookupVirtualDispatchTarget(
       DexClass dynamicInstance, AppInfoWithClassHierarchy appInfo);
 
   public abstract LookupTarget lookupVirtualDispatchTarget(
@@ -451,8 +450,9 @@
         // Only include if the target has code or is native.
         boolean isIncomplete =
             pinnedPredicate.isPinned(resolvedHolder) && pinnedPredicate.isPinned(resolvedMethod);
+        DexClassAndMethod resolutionPair = getResolutionPair();
         return LookupResult.createResult(
-            DexClassAndMethodSet.create(getResolutionPair()),
+            Collections.singletonMap(resolutionPair.getReference(), resolutionPair),
             Collections.emptyList(),
             Collections.emptyList(),
             isIncomplete
@@ -466,13 +466,12 @@
           initialResolutionHolder.type,
           subClass -> {
             incompleteness.checkClass(subClass);
-            DexClassAndMethod dexClassAndMethod =
+            LookupMethodTarget lookupTarget =
                 lookupVirtualDispatchTarget(
                     subClass, appInfo, resolvedHolder.type, resultBuilder::addMethodCausingFailure);
-            if (dexClassAndMethod != null) {
-              incompleteness.checkDexClassAndMethod(dexClassAndMethod);
-              addVirtualDispatchTarget(
-                  dexClassAndMethod, resolvedHolder.isInterface(), resultBuilder);
+            if (lookupTarget != null) {
+              incompleteness.checkDexClassAndMethod(lookupTarget);
+              addVirtualDispatchTarget(lookupTarget, resolvedHolder.isInterface(), resultBuilder);
             }
           },
           lambda -> {
@@ -552,10 +551,11 @@
     }
 
     private static void addVirtualDispatchTarget(
-        DexClassAndMethod target,
+        LookupMethodTarget target,
         boolean holderIsInterface,
         LookupResultSuccess.Builder resultBuilder) {
-      DexEncodedMethod targetMethod = target.getDefinition();
+      assert target.isMethodTarget();
+      DexEncodedMethod targetMethod = target.asMethodTarget().getDefinition();
       assert !targetMethod.isPrivateMethod();
       if (holderIsInterface) {
         // Add default interface methods to the list of targets.
@@ -609,7 +609,7 @@
     }
 
     @Override
-    public DexClassAndMethod lookupVirtualDispatchTarget(
+    public LookupMethodTarget lookupVirtualDispatchTarget(
         DexClass dynamicInstance, AppInfoWithClassHierarchy appInfo) {
       return lookupVirtualDispatchTarget(
           dynamicInstance, appInfo, initialResolutionHolder.type, emptyConsumer());
@@ -634,7 +634,7 @@
           lambdaInstance, appInfo, methodCausingFailureConsumer);
     }
 
-    private DexClassAndMethod lookupVirtualDispatchTarget(
+    private LookupMethodTarget lookupVirtualDispatchTarget(
         DexClass dynamicInstance,
         AppInfoWithClassHierarchy appInfo,
         DexType resolutionHolder,
@@ -644,18 +644,20 @@
       // TODO(b/148591377): Enable this assertion.
       // The dynamic type cannot be an interface.
       // assert !dynamicInstance.isInterface();
+      DexClassAndMethod initialResolutionPair = getResolutionPair();
       if (resolvedMethod.isPrivateMethod()) {
         // If the resolved reference is private there is no dispatch.
         // This is assuming that the method is accessible, which implies self/nest access.
-        return getResolutionPair();
+        return initialResolutionPair;
       }
       boolean allowPackageBlocked = resolvedMethod.accessFlags.isPackagePrivate();
       DexClass current = dynamicInstance;
-      DexEncodedMethod overrideTarget = resolvedMethod;
+      DexClassAndMethod overrideTarget = initialResolutionPair;
       while (current != null) {
-        DexEncodedMethod candidate = lookupOverrideCandidate(overrideTarget, current);
+        DexEncodedMethod candidate =
+            lookupOverrideCandidate(overrideTarget.getDefinition(), current);
         if (candidate == DexEncodedMethod.SENTINEL && allowPackageBlocked) {
-          overrideTarget = findWideningOverride(resolvedMethod, current, appInfo);
+          overrideTarget = findWideningOverride(initialResolutionPair, current, appInfo);
           allowPackageBlocked = false;
           continue;
         }
@@ -667,7 +669,10 @@
           current = current.superType == null ? null : appInfo.definitionFor(current.superType);
           continue;
         }
-        return DexClassAndMethod.create(current, candidate);
+        DexClassAndMethod target = DexClassAndMethod.create(current, candidate);
+        return overrideTarget != initialResolutionPair
+            ? new LookupMethodTargetWithAccessOverride(target, overrideTarget)
+            : target;
       }
       // If we have not found a candidate and the holder is not an interface it must be because the
       // class is missing.
@@ -732,10 +737,10 @@
       return null;
     }
 
-    private static DexEncodedMethod findWideningOverride(
-        DexEncodedMethod resolvedMethod, DexClass clazz, AppInfoWithClassHierarchy appView) {
+    private static DexClassAndMethod findWideningOverride(
+        DexClassAndMethod resolvedMethod, DexClass clazz, AppInfoWithClassHierarchy appView) {
       // Otherwise, lookup to first override that is distinct from resolvedMethod.
-      assert resolvedMethod.accessFlags.isPackagePrivate();
+      assert resolvedMethod.getDefinition().accessFlags.isPackagePrivate();
       while (clazz.superType != null) {
         clazz = appView.definitionFor(clazz.superType);
         if (clazz == null) {
@@ -743,10 +748,10 @@
         }
         DexEncodedMethod otherOverride = clazz.lookupVirtualMethod(resolvedMethod.getReference());
         if (otherOverride != null
-            && isOverriding(resolvedMethod, otherOverride)
+            && isOverriding(resolvedMethod.getDefinition(), otherOverride)
             && (otherOverride.accessFlags.isPublic() || otherOverride.accessFlags.isProtected())) {
-          assert resolvedMethod != otherOverride;
-          return otherOverride;
+          assert resolvedMethod.getDefinition() != otherOverride;
+          return DexClassAndMethod.create(clazz, otherOverride);
         }
       }
       return resolvedMethod;
@@ -818,19 +823,19 @@
     }
 
     @Override
-    public DexClassAndMethod lookupVirtualDispatchTarget(
+    public LookupTarget lookupVirtualDispatchTarget(
         InstantiatedObject instance, AppInfoWithClassHierarchy appInfo) {
       return null;
     }
 
     @Override
-    public DexClassAndMethod lookupVirtualDispatchTarget(
+    public LookupMethodTarget lookupVirtualDispatchTarget(
         DexClass dynamicInstance, AppInfoWithClassHierarchy appInfo) {
       return null;
     }
 
     @Override
-    public DexClassAndMethod lookupVirtualDispatchTarget(
+    public LookupTarget lookupVirtualDispatchTarget(
         LambdaDescriptor lambdaInstance,
         AppInfoWithClassHierarchy appInfo,
         Consumer<? super DexEncodedMethod> methodCausingFailureConsumer) {
@@ -1032,4 +1037,5 @@
       return invalidSymbolicReference.get();
     }
   }
+
 }
diff --git a/src/main/java/com/android/tools/r8/graph/analysis/ApiModelAnalysis.java b/src/main/java/com/android/tools/r8/graph/analysis/ApiModelAnalysis.java
index 45e2065..e35cd85 100644
--- a/src/main/java/com/android/tools/r8/graph/analysis/ApiModelAnalysis.java
+++ b/src/main/java/com/android/tools/r8/graph/analysis/ApiModelAnalysis.java
@@ -64,7 +64,7 @@
   @Override
   public void notifyMarkVirtualDispatchTargetAsLive(LookupTarget target) {
     target.accept(
-        this::computeAndSetApiLevelForDefinition,
+        lookupMethodTarget -> computeAndSetApiLevelForDefinition(lookupMethodTarget.getTarget()),
         lookupLambdaTarget -> {
           // The implementation method will be assigned an api level when visited.
         });
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
index efbcd4c..69f3404 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethod.java
@@ -164,7 +164,8 @@
     }
     ProgramMethodSet result = ProgramMethodSet.create();
     lookupResult.forEach(
-        methodTarget -> {
+        target -> {
+          DexClassAndMethod methodTarget = target.getTarget();
           if (methodTarget.isProgramMethod()) {
             result.add(methodTarget.asProgramMethod());
           }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java b/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
index 58bfafa..3ff7bed 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/CallGraphBuilderBase.java
@@ -227,7 +227,8 @@
                     lookupResult
                         .asLookupResultSuccess()
                         .forEach(
-                            methodTarget -> {
+                            lookupMethodTarget -> {
+                              DexClassAndMethod methodTarget = lookupMethodTarget.getTarget();
                               if (methodTarget.isProgramMethod()) {
                                 targets.add(methodTarget.asProgramMethod());
                               }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
index 36519f8..48d399f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/itf/ClassProcessor.java
@@ -25,6 +25,7 @@
 import com.android.tools.r8.graph.GenericSignature;
 import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
 import com.android.tools.r8.graph.LibraryMethod;
+import com.android.tools.r8.graph.LookupMethodTarget;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.MethodResolutionResult;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -718,8 +719,9 @@
       }
     }
     assert resolutionResult.isSuccessfulMemberResolutionResult();
-    DexClassAndMethod virtualDispatchTarget =
+    LookupMethodTarget lookupMethodTarget =
         resolutionResult.lookupVirtualDispatchTarget(clazz, appInfo);
+    DexClassAndMethod virtualDispatchTarget = lookupMethodTarget.getTarget();
     assert virtualDispatchTarget != null;
 
     // Don't forward if the target is explicitly marked as 'dont-rewrite'
diff --git a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
index c34f7f3..bc5fa43 100644
--- a/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
+++ b/src/main/java/com/android/tools/r8/shaking/AppInfoWithLiveness.java
@@ -36,6 +36,7 @@
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.GraphLens.NonIdentityGraphLens;
 import com.android.tools.r8.graph.InstantiatedSubTypeInfo;
+import com.android.tools.r8.graph.LookupMethodTarget;
 import com.android.tools.r8.graph.LookupResult.LookupResultSuccess;
 import com.android.tools.r8.graph.LookupTarget;
 import com.android.tools.r8.graph.MethodAccessInfoCollection;
@@ -1509,17 +1510,17 @@
     if (receiverLowerBoundType != null
         && receiverLowerBoundType.getClassType() == refinedReceiverType) {
       if (refinedReceiverClass.isProgramClass()) {
-        DexClassAndMethod clazzAndMethod =
+        LookupMethodTarget methodTarget =
             resolution.lookupVirtualDispatchTarget(refinedReceiverClass.asProgramClass(), this);
-        if (clazzAndMethod == null
-            || (clazzAndMethod.isProgramMethod()
+        if (methodTarget == null
+            || (methodTarget.getTarget().isProgramMethod()
                 && !getKeepInfo()
-                    .getMethodInfo(clazzAndMethod.asProgramMethod())
+                    .getMethodInfo(methodTarget.getTarget().asProgramMethod())
                     .isOptimizationAllowed(options()))) {
           // TODO(b/150640456): We should maybe only consider program methods.
           return DexEncodedMethod.SENTINEL;
         }
-        return clazzAndMethod.getDefinition();
+        return methodTarget.getDefinition();
       } else {
         // TODO(b/150640456): We should maybe only consider program methods.
         // If we resolved to a method on the refined receiver in the library, then we report the
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index dbe1c2e..1d4c627 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -64,6 +64,7 @@
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.graph.InvalidCode;
 import com.android.tools.r8.graph.LookupLambdaTarget;
+import com.android.tools.r8.graph.LookupMethodTarget;
 import com.android.tools.r8.graph.LookupResult;
 import com.android.tools.r8.graph.LookupTarget;
 import com.android.tools.r8.graph.MethodAccessInfoCollection;
@@ -3042,20 +3043,25 @@
   private void markVirtualDispatchTargetAsLive(
       LookupTarget target, Function<ProgramMethod, KeepReasonWitness> reason) {
     target.accept(
-        method -> markVirtualDispatchTargetAsLive(method, reason),
-        lambda -> markVirtualDispatchTargetAsLive(lambda, reason));
+        method -> markVirtualDispatchMethodTargetAsLive(method, reason),
+        lambda -> markVirtualDispatchLambdaTargetAsLive(lambda, reason));
     analyses.forEach(analysis -> analysis.notifyMarkVirtualDispatchTargetAsLive(target));
   }
 
-  private void markVirtualDispatchTargetAsLive(
-      DexClassAndMethod target, Function<ProgramMethod, KeepReasonWitness> reason) {
-    ProgramMethod programMethod = target.asProgramMethod();
+  private void markVirtualDispatchMethodTargetAsLive(
+      LookupMethodTarget target, Function<ProgramMethod, KeepReasonWitness> reason) {
+    ProgramMethod programMethod = target.getTarget().asProgramMethod();
     if (programMethod != null && !programMethod.getDefinition().isAbstract()) {
-      markVirtualMethodAsLive(programMethod, reason.apply(programMethod));
+      KeepReasonWitness appliedReason = reason.apply(programMethod);
+      markVirtualMethodAsLive(programMethod, appliedReason);
+      DexClassAndMethod accessOverride = target.getAccessOverride();
+      if (accessOverride != null && accessOverride.isProgramMethod()) {
+        markMethodAsTargeted(accessOverride.asProgramMethod(), appliedReason);
+      }
     }
   }
 
-  private void markVirtualDispatchTargetAsLive(
+  private void markVirtualDispatchLambdaTargetAsLive(
       LookupLambdaTarget target, Function<ProgramMethod, KeepReasonWitness> reason) {
     ProgramMethod implementationMethod = target.getImplementationMethod().asProgramMethod();
     if (implementationMethod != null) {
@@ -4171,7 +4177,7 @@
     if (override.isLambdaTarget()) {
       return true;
     }
-    ProgramMethod programMethod = override.asMethodTarget().asProgramMethod();
+    ProgramMethod programMethod = override.asMethodTarget().getTarget().asProgramMethod();
     if (programMethod == null) {
       return false;
     }
diff --git a/src/test/java/com/android/tools/r8/examples/abstractmethodremoval/AbstractMethodRemovalTestRunner.java b/src/test/java/com/android/tools/r8/examples/abstractmethodremoval/AbstractMethodRemovalTestRunner.java
index 66f9713..39d93b9 100644
--- a/src/test/java/com/android/tools/r8/examples/abstractmethodremoval/AbstractMethodRemovalTestRunner.java
+++ b/src/test/java/com/android/tools/r8/examples/abstractmethodremoval/AbstractMethodRemovalTestRunner.java
@@ -6,7 +6,6 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper.DexVm.Version;
 import com.android.tools.r8.examples.abstractmethodremoval.a.PackageBase;
 import com.android.tools.r8.examples.abstractmethodremoval.a.Public;
 import com.android.tools.r8.examples.abstractmethodremoval.b.Impl1;
@@ -66,10 +65,6 @@
         .addKeepMainRule(getMainClass())
         .setMinApi(parameters.getApiLevel())
         .run(parameters.getRuntime(), getMainClass())
-        .applyIf(
-            // TODO(b/227302144): The program should not fail after R8.
-            parameters.isCfRuntime(),
-            r -> r.assertFailure(),
-            r -> r.assertSuccessWithOutput(getExpected()));
+        .assertSuccessWithOutput(getExpected());
   }
 }