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