Disallow merge when invoke-super resolves to private method
This CL prevents a class A from being merged into its subclass B if there is an invoke-super instruction that resolves to a private method in A. This is needed to ensure that the program will continue to yield an IllegalAccessError.
This case is caught by the test MemberResolutionTest.lookupPrivateSuperFromSubClass.
Change-Id: I3d8297e261fee6391f16c606d9368e18d0460e11
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 77a369d..baacb1e 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -112,7 +112,10 @@
private final Set<DexField> protoLiteFields = Sets.newIdentityHashSet();
private final Set<DexItem> identifierNameStrings = Sets.newIdentityHashSet();
- /** Set of method signatures used in invoke-super instructions that cannot be resolved. */
+ /**
+ * Set of method signatures used in invoke-super instructions that either cannot be resolved or
+ * resolve to a private method (leading to an IllegalAccessError).
+ */
private final Set<DexMethod> brokenSuperInvokes = Sets.newIdentityHashSet();
/**
* This map keeps a view of all virtual methods that are reachable from virtual invokes. A method
@@ -1032,6 +1035,9 @@
reportMissingMethod(method);
return;
}
+ if (target.accessFlags.isPrivate()) {
+ brokenSuperInvokes.add(method);
+ }
assert !superInvokeDependencies.containsKey(from) || !superInvokeDependencies.get(from)
.contains(target);
if (Log.ENABLED) {
@@ -1520,7 +1526,10 @@
* Set of all methods referenced in static invokes;
*/
public final SortedSet<DexMethod> staticInvokes;
- /** Set of method signatures used in invoke-super instructions that cannot be resolved. */
+ /**
+ * Set of method signatures used in invoke-super instructions that either cannot be resolved or
+ * resolve to a private method (leading to an IllegalAccessError).
+ */
public final SortedSet<DexMethod> brokenSuperInvokes;
/**
* Set of all items that have to be kept independent of whether they are used.