Reproduce incorrect lens lookup for non-rebound method reference
Bug: b/312135155
Change-Id: I27e574b2f4ba154b5b392c79a5f94b36935e7224
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 2819a74..b51e3cd 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -2403,6 +2403,7 @@
public boolean enableEnumUnboxingDebugLogs =
System.getProperty("com.android.tools.r8.enableEnumUnboxingDebugLogs") != null;
public boolean enableEnumWithSubtypesUnboxing = true;
+ public boolean enableVerticalClassMergerLensAssertion = false;
public boolean forceRedundantConstNumberRemoval = false;
public boolean enableExperimentalDesugaredLibraryKeepRuleGenerator = false;
public boolean invertConditionals = false;
diff --git a/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMergerGraphLens.java b/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMergerGraphLens.java
index 1a08e65..e3ad747 100644
--- a/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMergerGraphLens.java
+++ b/src/main/java/com/android/tools/r8/verticalclassmerging/VerticalClassMergerGraphLens.java
@@ -26,6 +26,7 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Streams;
import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Map;
@@ -133,16 +134,23 @@
}
}
}
+ MethodLookupResult lookupResult;
DexMethod newMethod = methodMap.apply(previous.getReference());
if (newMethod == null) {
- return previous;
+ lookupResult = previous;
+ } else {
+ lookupResult =
+ MethodLookupResult.builder(this)
+ .setReference(newMethod)
+ .setPrototypeChanges(
+ internalDescribePrototypeChanges(previous.getPrototypeChanges(), newMethod))
+ .setType(mapInvocationType(newMethod, previous.getReference(), previous.getType()))
+ .build();
}
- return MethodLookupResult.builder(this)
- .setReference(newMethod)
- .setPrototypeChanges(
- internalDescribePrototypeChanges(previous.getPrototypeChanges(), newMethod))
- .setType(mapInvocationType(newMethod, previous.getReference(), previous.getType()))
- .build();
+ assert !appView.testing().enableVerticalClassMergerLensAssertion
+ || Streams.stream(lookupResult.getReference().getReferencedBaseTypes(dexItemFactory()))
+ .noneMatch(type -> mergedClasses.hasBeenMergedIntoSubtype(type));
+ return lookupResult;
}
@Override
diff --git a/src/test/java/com/android/tools/r8/classmerging/vertical/IncorrectRewritingOfInvokeSuperTest.java b/src/test/java/com/android/tools/r8/classmerging/vertical/IncorrectRewritingOfInvokeSuperTest.java
index 93aad99..8cd641d 100644
--- a/src/test/java/com/android/tools/r8/classmerging/vertical/IncorrectRewritingOfInvokeSuperTest.java
+++ b/src/test/java/com/android/tools/r8/classmerging/vertical/IncorrectRewritingOfInvokeSuperTest.java
@@ -4,10 +4,16 @@
package com.android.tools.r8.classmerging.vertical;
+import static org.junit.Assert.assertTrue;
+
import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.Box;
+import com.android.tools.r8.utils.codeinspector.AssertUtils;
+import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -21,22 +27,41 @@
@Parameter(0)
public TestParameters parameters;
- @Parameters(name = "{0}")
- public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
+ @Parameter(1)
+ public boolean verifyLensLookup;
+
+ @Parameters(name = "{0}, verify: {1}")
+ public static List<Object[]> data() {
+ return buildParameters(
+ getTestParameters().withAllRuntimesAndApiLevels().build(), BooleanUtils.values());
}
@Test
public void test() throws Exception {
- testForR8(parameters.getBackend())
- .addInnerClasses(IncorrectRewritingOfInvokeSuperTest.class)
- .addKeepMainRule(TestClass.class)
- .addOptionsModification(options -> options.enableUnusedInterfaceRemoval = false)
- .enableInliningAnnotations()
- .addDontObfuscate()
- .setMinApi(parameters)
- .run(parameters.getRuntime(), TestClass.class)
- .assertSuccess();
+ Box<R8TestCompileResult> compileResult = new Box<>();
+ AssertUtils.assertFailsCompilationIf(
+ verifyLensLookup,
+ () ->
+ compileResult.set(
+ testForR8(parameters.getBackend())
+ .addInnerClasses(IncorrectRewritingOfInvokeSuperTest.class)
+ .addKeepMainRule(TestClass.class)
+ .addOptionsModification(
+ options -> {
+ options.enableUnusedInterfaceRemoval = false;
+ options.testing.enableVerticalClassMergerLensAssertion = verifyLensLookup;
+ })
+ .enableInliningAnnotations()
+ .addDontObfuscate()
+ .setMinApi(parameters)
+ .compile()));
+
+ if (!compileResult.isSet()) {
+ assertTrue(verifyLensLookup);
+ return;
+ }
+
+ compileResult.get().run(parameters.getRuntime(), TestClass.class).assertSuccess();
}
static class TestClass {