Desugare nest based access for invoke-special instructions in R8.
Bug: 145187969
Bug: 146124603
Change-Id: Ifba0c60a0dd03d885700e6ffa3992e9739b4d77a
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 7ef6cd5..6233a57 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -470,6 +470,10 @@
return true;
}
+ public DexEncodedMethod getMethod() {
+ return method;
+ }
+
public boolean isDebugMode() {
return appView.options().debug || method.getOptimizationInfo().isReachabilitySensitive();
}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
index ff95053..30edf6a 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
@@ -385,8 +385,7 @@
@Override
public boolean registerInvokeSuper(DexMethod method) {
- // Cannot target private method.
- return false;
+ return registerInvoke(method, Invoke.Type.SUPER);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
index 1784753..98e83c4 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
@@ -9,11 +9,10 @@
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.analysis.type.Nullability;
-import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.CatchHandlers;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.ValueType;
+import com.android.tools.r8.ir.conversion.DexSourceCode;
import com.android.tools.r8.ir.conversion.IRBuilder;
import com.android.tools.r8.ir.conversion.SourceCode;
import java.util.ArrayList;
@@ -25,6 +24,7 @@
protected final static Predicate<IRBuilder> doesNotEndBlock = x -> false;
protected final static Predicate<IRBuilder> endsBlock = x -> true;
+ // TODO(b/146124603): Remove these fields as optimzations (e.g., merging) could invalidate them.
protected final DexType receiver;
protected final DexMethod method;
protected final DexProto proto;
@@ -156,19 +156,11 @@
@Override
public final void buildPrelude(IRBuilder builder) {
- if (receiver != null) {
- builder.addThisArgument(
- receiverRegister,
- TypeLatticeElement.fromDexType(
- receiver, Nullability.definitelyNotNull(), builder.appView));
- }
- // Fill in the Argument instructions in the argument block.
- DexType[] parameters = proto.parameters.values;
- for (int i = 0; i < parameters.length; i++) {
- TypeLatticeElement typeLattice =
- TypeLatticeElement.fromDexType(parameters[i], Nullability.maybeNull(), builder.appView);
- builder.addNonThisArgument(paramRegisters[i], typeLattice);
- }
+ DexSourceCode.buildArgumentsWithUnusedArgumentStubs(
+ builder,
+ 0,
+ builder.getMethod(),
+ DexSourceCode::doNothingWriteConsumer);
}
@Override
diff --git a/src/test/java/com/android/tools/r8/TestRunResult.java b/src/test/java/com/android/tools/r8/TestRunResult.java
index 6170af1..e1ebfa2 100644
--- a/src/test/java/com/android/tools/r8/TestRunResult.java
+++ b/src/test/java/com/android/tools/r8/TestRunResult.java
@@ -96,7 +96,7 @@
assertThat(
errorMessage("Run stderr incorrect.", expectedError.getName()),
result.stderr,
- containsString(expectedError.getName() + ":"));
+ containsString(expectedError.getName()));
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 9d9b8c5..a9dc70f 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
@@ -174,7 +174,7 @@
.addProgramClasses(getClasses())
.addProgramClassFileData(getTransformedClasses())
.run(parameters.getRuntime(), Main.class)
- .apply(result -> checkExpectedResult(result, false));
+ .apply(this::checkExpectedResult);
}
@Test
@@ -185,16 +185,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) {
- if (isR8 && parameters.isDexRuntime() && inSameNest && symbolicReferenceIsDefiningType) {
- // TODO(b/145187969): Incorrect nest desugaring.
- result.assertFailureWithErrorThatThrows(VerifyError.class);
- return;
- }
-
+ private void checkExpectedResult(TestRunResult<?> result) {
if (!symbolicReferenceIsDefiningType) {
result.assertFailureWithErrorThatThrows(NoSuchMethodError.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 508e851..490b7dc 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
@@ -149,7 +149,7 @@
.addProgramClasses(getClasses())
.addProgramClassFileData(getTransformedClasses())
.run(parameters.getRuntime(), Main.class)
- .apply(result -> checkExpectedResult(result, false));
+ .apply(this::checkExpectedResult);
}
@Test
@@ -160,17 +160,12 @@
.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) {
if (inSameNest) {
- if (isR8 && parameters.isDexRuntime()) {
- // TODO(b/145187969): R8 incorrectly compiles the nest based access away.
- result.assertFailureWithErrorThatThrows(VerifyError.class);
- } else {
- result.assertSuccessWithOutput(EXPECTED);
- }
+ result.assertSuccessWithOutput(EXPECTED);
} else {
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 d5f612d..52dbd4b 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
@@ -201,8 +201,8 @@
// 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()) {
+ // TODO(b/145775365): R8 incorrectly compiles the input to a working program.
+ if (isR8) {
result.assertSuccessWithOutput(EXPECTED);
return;
}
@@ -216,11 +216,6 @@
}
// 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);
}
diff --git a/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessWithIntermediateClassTest.java b/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessWithIntermediateClassTest.java
index d6343fc..3e85f1a 100644
--- a/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessWithIntermediateClassTest.java
+++ b/src/test/java/com/android/tools/r8/resolution/access/NestVirtualMethodAccessWithIntermediateClassTest.java
@@ -4,12 +4,8 @@
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.fail;
-import com.android.tools.r8.CompilationFailedException;
-import com.android.tools.r8.R8FullTestBuilder;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRunResult;
@@ -89,31 +85,20 @@
@Test
public void testR8() throws Exception {
- R8FullTestBuilder builder =
- testForR8(parameters.getBackend())
- .addProgramClasses(getClasses())
- .addProgramClassFileData(getTransformedClasses())
- .setMinApi(parameters.getApiLevel())
- .addKeepMainRule(Main.class);
- // TODO(b/145196085): R8 fails compilation when the classes are in the same nest.
- if (inSameNest) {
- if (parameters.isDexRuntime()) {
- try {
- builder.compile();
- } catch (CompilationFailedException e) {
- // Expected failure.
- return;
- }
- fail("Expected failure: b/145196085");
- }
- }
- builder
+ testForR8(parameters.getBackend())
+ .addProgramClasses(getClasses())
+ .addProgramClassFileData(getTransformedClasses())
+ .setMinApi(parameters.getApiLevel())
+ .addKeepMainRule(Main.class)
.run(parameters.getRuntime(), Main.class)
.apply(
result -> {
- if (inSameNest) {
- // TODO(b/145187969): R8 compiles out the errors when in the same nest.
+ if (inSameNest && parameters.isCfRuntime()) {
+ // TODO(b/145187969): R8/CF compiles to a "working" program.
result.assertSuccessWithOutput(EXPECTED);
+ } else if (inSameNest && parameters.isDexRuntime()) {
+ // TODO(b/145187969): R8/DEX compiles to a throw null program.
+ result.assertFailureWithErrorThatThrows(NullPointerException.class);
} else {
checkExpectedResult(result);
}
@@ -123,9 +108,9 @@
private void checkExpectedResult(TestRunResult<?> result) {
if (inSameNest && parameters.isCfRuntime()) {
// TODO(b/145187969): Investigate if the change to NoSuchMethodError is according to spec?
- result.assertFailureWithErrorThatMatches(containsString(NoSuchMethodError.class.getName()));
+ result.assertFailureWithErrorThatThrows(NoSuchMethodError.class);
} else {
- result.assertFailureWithErrorThatMatches(containsString(IllegalAccessError.class.getName()));
+ result.assertFailureWithErrorThatThrows(IllegalAccessError.class);
}
}