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 3561bff..d616716 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1704,6 +1704,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.