Small regression test for invalid exceptional transfers.
Bug: b/237567012
Change-Id: I8ac44f7df25f0a0ca28ed8a02c4a2a2946043bd9
diff --git a/src/main/java/com/android/tools/r8/cf/CfRegisterAllocator.java b/src/main/java/com/android/tools/r8/cf/CfRegisterAllocator.java
index 351a3a1..b9ef649 100644
--- a/src/main/java/com/android/tools/r8/cf/CfRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/cf/CfRegisterAllocator.java
@@ -284,6 +284,9 @@
}
private void freeRegistersForIntervals(LiveIntervals intervals) {
+ if (options().testing.neverReuseCfLocalRegisters) {
+ return;
+ }
int register = intervals.getRegister();
freeRegisters.add(register);
if (intervals.getType().isWide()) {
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 aa1509b..f5e86e9 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1769,6 +1769,7 @@
public static class TestingOptions {
+ public boolean neverReuseCfLocalRegisters = false;
private boolean hasReadCheckDeterminism = false;
private DeterminismChecker determinismChecker = null;
diff --git a/src/test/java/com/android/tools/r8/cf/CfDebugLocalStackMapVerificationTest.java b/src/test/java/com/android/tools/r8/cf/CfDebugLocalStackMapVerificationTest.java
index 32ce06a..5108c8d 100644
--- a/src/test/java/com/android/tools/r8/cf/CfDebugLocalStackMapVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/cf/CfDebugLocalStackMapVerificationTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.cf;
+import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.assertThrows;
import com.android.tools.r8.CompilationFailedException;
@@ -11,6 +12,7 @@
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.AndroidApiLevel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -23,8 +25,8 @@
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
+/** Regression tests for b/237567012 */
@RunWith(Parameterized.class)
-/** This is a regresson test for b/237567012 */
public class CfDebugLocalStackMapVerificationTest extends TestBase {
@Parameter() public TestParameters parameters;
@@ -34,6 +36,43 @@
return getTestParameters().withCfRuntimes().build();
}
+ static class SmallRepro {
+
+ public static void main(String[] args) {
+ RuntimeException x = new RuntimeException("FOO");
+ RuntimeException c = null;
+ try {
+ c = x;
+ throw c;
+ } catch (RuntimeException e) {
+ System.out.println(c);
+ }
+ }
+ }
+
+ @Test
+ public void testReference() throws Exception {
+ testForJvm()
+ .addProgramClasses(SmallRepro.class)
+ .run(parameters.getRuntime(), SmallRepro.class)
+ .assertSuccessWithOutputThatMatches(containsString("FOO"));
+ }
+
+ @Test
+ public void testSmallReproD8() throws Exception {
+ testForD8(parameters.getBackend())
+ .addProgramClasses(SmallRepro.class)
+ .setMinApi(AndroidApiLevel.B)
+ .addOptionsModification(
+ options -> {
+ options.testing.forceIRForCfToCfDesugar = true;
+ options.testing.neverReuseCfLocalRegisters = true;
+ })
+ .run(parameters.getRuntime(), SmallRepro.class)
+ // TODO(b/237567012): Run should succeed with printing of FOO.
+ .assertFailureWithErrorThatThrows(VerifyError.class);
+ }
+
@Test
public void testR8() throws Exception {
// TODO(b/237567012): We should not fail compilation.