Desugare nest based access for invoke-special instructions.
Bug: 145775365
Change-Id: I696cf095f4353845e6ed87a994da4a31f0694747
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/D8NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/D8NestBasedAccessDesugaring.java
index 68a8bd4..e4af36c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/D8NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/D8NestBasedAccessDesugaring.java
@@ -62,7 +62,7 @@
InstructionListIterator instructions = block.listIterator(code);
while (instructions.hasNext()) {
Instruction instruction = instructions.next();
- if (instruction.isInvokeMethod() && !instruction.isInvokeSuper()) {
+ if (instruction.isInvokeMethod()) {
InvokeMethod invokeMethod = instruction.asInvokeMethod();
DexMethod methodCalled = invokeMethod.getInvokedMethod();
DexEncodedMethod encodedMethodCalled =
diff --git a/src/test/java/com/android/tools/r8/TestRunResult.java b/src/test/java/com/android/tools/r8/TestRunResult.java
index f286bac..6170af1 100644
--- a/src/test/java/com/android/tools/r8/TestRunResult.java
+++ b/src/test/java/com/android/tools/r8/TestRunResult.java
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@@ -90,6 +91,15 @@
return self();
}
+ public RR assertFailureWithErrorThatThrows(Class<? extends Throwable> expectedError) {
+ assertFailure();
+ assertThat(
+ errorMessage("Run stderr incorrect.", expectedError.getName()),
+ result.stderr,
+ containsString(expectedError.getName() + ":"));
+ return self();
+ }
+
public RR assertStderrMatches(Matcher<String> matcher) {
assertThat(errorMessage("Run stderr incorrect.", matcher.toString()), result.stderr, matcher);
return self();
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialInterfaceMethodAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialInterfaceMethodAccessTest.java
index d0d4398..9d9b8c5 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialInterfaceMethodAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialInterfaceMethodAccessTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.resolution.access;
import static com.android.tools.r8.TestRuntime.CfVm.JDK11;
-import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -192,29 +191,20 @@
private void checkExpectedResult(TestRunResult<?> result, boolean isR8) {
if (isR8 && parameters.isDexRuntime() && inSameNest && symbolicReferenceIsDefiningType) {
// TODO(b/145187969): Incorrect nest desugaring.
- result.assertFailureWithErrorThatMatches(containsString(VerifyError.class.getName()));
+ result.assertFailureWithErrorThatThrows(VerifyError.class);
return;
}
if (!symbolicReferenceIsDefiningType) {
- result.assertFailureWithErrorThatMatches(containsString(NoSuchMethodError.class.getName()));
- return;
- }
-
- if (isDesugaring()) {
- // TODO(b/145775365): Desugaring results in an incorrect program.
- result.assertFailureWithErrorThatMatches(containsString(NoSuchMethodError.class.getName()));
+ result.assertFailureWithErrorThatThrows(NoSuchMethodError.class);
return;
}
if (!inSameNest) {
- result.assertFailureWithErrorThatMatches(containsString(IllegalAccessError.class.getName()));
- return;
- }
-
- if (parameters.isDexRuntime()) {
- // TODO(b/145187969): Incorrect nest desugaring.
- result.assertFailureWithErrorThatMatches(containsString(IllegalAccessError.class.getName()));
+ // TODO(b/145775365): Desugaring causes change to reported error.
+ // The default method desugar will target $default$bar, but the definition is $private$bar.
+ result.assertFailureWithErrorThatThrows(
+ isDesugaring() ? NoSuchMethodError.class : IllegalAccessError.class);
return;
}
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessTest.java
index 8d54c3a..508e851 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.resolution.access;
import static com.android.tools.r8.TestRuntime.CfVm.JDK11;
-import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -166,19 +165,14 @@
private void checkExpectedResult(TestRunResult<?> result, boolean isR8) {
if (inSameNest) {
- if (parameters.isDexRuntime()) {
- // TODO(b/145187969): D8/R8 incorrectly compiles the nest based access away.
- if (isR8) {
- result.assertFailureWithErrorThatMatches(containsString(VerifyError.class.getName()));
- } else {
- result.assertFailureWithErrorThatMatches(
- containsString(IllegalAccessError.class.getName()));
- }
+ if (isR8 && parameters.isDexRuntime()) {
+ // TODO(b/145187969): R8 incorrectly compiles the nest based access away.
+ result.assertFailureWithErrorThatThrows(VerifyError.class);
} else {
result.assertSuccessWithOutput(EXPECTED);
}
} else {
- result.assertFailureWithErrorThatMatches(containsString(IllegalAccessError.class.getName()));
+ result.assertFailureWithErrorThatThrows(IllegalAccessError.class);
}
}
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessWithIntermediateTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessWithIntermediateTest.java
index 3f5efb9..d5f612d 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessWithIntermediateTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodAccessWithIntermediateTest.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.resolution.access;
import static com.android.tools.r8.TestRuntime.CfVm.JDK11;
-import static org.hamcrest.core.StringContains.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -194,18 +193,35 @@
}
private void checkExpectedResult(TestRunResult<?> result, boolean isR8) {
- if (inSameNest && parameters.isCfRuntime()) {
- if (isR8) {
- // TODO(b/145775365): R8 incorrectly compiles the input.
- result.assertSuccessWithOutput(EXPECTED);
- } else if (symbolicReferenceIsDefiningType) {
- result.assertSuccessWithOutput(EXPECTED);
- } else {
- result.assertFailureWithErrorThatMatches(containsString(NoSuchMethodError.class.getName()));
- }
- } else {
- result.assertFailureWithErrorThatMatches(containsString(IllegalAccessError.class.getName()));
+ // If not in the same nest, the error is always illegal access.
+ if (!inSameNest) {
+ result.assertFailureWithErrorThatThrows(IllegalAccessError.class);
+ return;
}
+
+ // If in the same nest but the reference is not exact, the error is always no such method.
+ if (!symbolicReferenceIsDefiningType) {
+ // TODO(b/145775365): R8/CF incorrectly compiles the input to a working program.
+ if (isR8 && parameters.isCfRuntime()) {
+ result.assertSuccessWithOutput(EXPECTED);
+ return;
+ }
+ // TODO(b/145775365): D8/R8 does not preserve the thrown error.
+ if (parameters.isDexRuntime()) {
+ result.assertFailureWithErrorThatThrows(IllegalAccessError.class);
+ return;
+ }
+ result.assertFailureWithErrorThatThrows(NoSuchMethodError.class);
+ return;
+ }
+
+ // Finally, if in the same nest and the reference is exact match the program runs successfully.
+ // TODO(b/145775365): R8/DEX incorrectly compiles the input to a non-working program.
+ if (isR8 && parameters.isDexRuntime()) {
+ result.assertFailureWithErrorThatThrows(IllegalAccessError.class);
+ return;
+ }
+ result.assertSuccessWithOutput(EXPECTED);
}
static class A {
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodPublicAccessWithIntermediateTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodPublicAccessWithIntermediateTest.java
index c45ec8b..49426c4 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodPublicAccessWithIntermediateTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestInvokeSpecialMethodPublicAccessWithIntermediateTest.java
@@ -145,7 +145,7 @@
.addProgramClasses(getClasses())
.addProgramClassFileData(getTransformedClasses())
.run(parameters.getRuntime(), Main.class)
- .apply(result -> checkExpectedResult(result, false));
+ .apply(this::checkExpectedResult);
}
@Test
@@ -156,10 +156,10 @@
.setMinApi(parameters.getApiLevel())
.addKeepMainRule(Main.class)
.run(parameters.getRuntime(), Main.class)
- .apply(result -> checkExpectedResult(result, true));
+ .apply(this::checkExpectedResult);
}
- private void checkExpectedResult(TestRunResult<?> result, boolean isR8) {
+ private void checkExpectedResult(TestRunResult<?> result) {
result.assertSuccessWithOutput(EXPECTED);
}