Update and move 680-sink-regression into 639-checker-code-sinking

test/680-sink-regression was passing with and without its relevant
code so it wasn't working as a regression test. Move the relevant
bits out of it and into 639-checker-code-sinking which will fail
if we remove the relevant code from the codebase.

Bug: 226143661
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: I4eac4852a0d6279bbe3ca8f041a27113d7d57be4
diff --git a/test/639-checker-code-sinking/src/Main.java b/test/639-checker-code-sinking/src/Main.java
index 4becc11..743d501 100644
--- a/test/639-checker-code-sinking/src/Main.java
+++ b/test/639-checker-code-sinking/src/Main.java
@@ -26,6 +26,7 @@
     testNoUse();
     testPhiInput();
     testVolatileStore();
+    testCatchBlock();
     doThrow = true;
     try {
       testInstanceSideEffects();
@@ -46,7 +47,6 @@
       // expected
       System.out.println(e.getMessage());
     }
-    testCatchBlock();
   }
 
   /// CHECK-START: void Main.testSimpleUse() code_sinking (before)
@@ -399,6 +399,8 @@
     assertEquals(456, testSinkRightBeforeTryBlock());
     assertEquals(456, testSinkToSecondCatch());
     assertEquals(456, testDoNotSinkToCatchInsideTryWithMoreThings(false, false));
+    assertEquals(456, testSinkToCatchBlockCustomClass());
+    assertEquals(456, DoNotSinkWithOOMThrow());
   }
 
   /// CHECK-START: int Main.testSinkToCatchBlock() code_sinking (before)
@@ -610,6 +612,76 @@
     return 456;
   }
 
+  private static class ObjectWithInt {
+    int x;
+  }
+
+  /// CHECK-START: int Main.testSinkToCatchBlockCustomClass() code_sinking (before)
+  /// CHECK: <<LoadClass:l\d+>>      LoadClass class_name:Main$ObjectWithInt
+  /// CHECK: <<Clinit:l\d+>>         ClinitCheck [<<LoadClass>>]
+  /// CHECK:                         NewInstance [<<Clinit>>]
+  /// CHECK:                         TryBoundary kind:entry
+
+  /// CHECK-START: int Main.testSinkToCatchBlockCustomClass() code_sinking (after)
+  /// CHECK: <<LoadClass:l\d+>>      LoadClass class_name:Main$ObjectWithInt
+  /// CHECK: <<Clinit:l\d+>>         ClinitCheck [<<LoadClass>>]
+  /// CHECK:                         TryBoundary kind:entry
+  /// CHECK:                         NewInstance [<<Clinit>>]
+
+  // Consistency check to make sure there's only one entry TryBoundary.
+  /// CHECK-START: int Main.testSinkToCatchBlockCustomClass() code_sinking (after)
+  /// CHECK:                         TryBoundary kind:entry
+  /// CHECK-NOT:                     TryBoundary kind:entry
+
+  // Similar to testSinkToCatchBlock, but using a custom class. CLinit check is not an instruction
+  // that we sink since it can throw and it is not in the allow list. We can sink the NewInstance
+  // nevertheless.
+  private static int testSinkToCatchBlockCustomClass() {
+    ObjectWithInt obj = new ObjectWithInt();
+    try {
+      if (doEarlyReturn) {
+        return 123;
+      }
+    } catch (Error e) {
+      throw new Error(Integer.toString(obj.x));
+    }
+    return 456;
+  }
+
+  /// CHECK-START: int Main.DoNotSinkWithOOMThrow() code_sinking (before)
+  /// CHECK: <<LoadClass:l\d+>>      LoadClass class_name:Main$ObjectWithInt
+  /// CHECK: <<Clinit:l\d+>>         ClinitCheck [<<LoadClass>>]
+  /// CHECK:                         NewInstance [<<Clinit>>]
+  /// CHECK:                         TryBoundary kind:entry
+
+  /// CHECK-START: int Main.DoNotSinkWithOOMThrow() code_sinking (after)
+  /// CHECK: <<LoadClass:l\d+>>      LoadClass class_name:Main$ObjectWithInt
+  /// CHECK: <<Clinit:l\d+>>         ClinitCheck [<<LoadClass>>]
+  /// CHECK:                         NewInstance [<<Clinit>>]
+  /// CHECK:                         TryBoundary kind:entry
+
+  // Consistency check to make sure there's only one entry TryBoundary.
+  /// CHECK-START: int Main.DoNotSinkWithOOMThrow() code_sinking (after)
+  /// CHECK:                         TryBoundary kind:entry
+  /// CHECK-NOT:                     TryBoundary kind:entry
+  private static int DoNotSinkWithOOMThrow() throws OutOfMemoryError {
+    int x = 0;
+    ObjectWithInt obj = new ObjectWithInt();
+    try {
+      // We want an if/else here so that the catch block will have a catch phi.
+      if (doThrow) {
+        x = 1;
+        // Doesn't really matter what we throw we just want it to not be caught by the
+        // NullPointerException below.
+        throw new OutOfMemoryError(Integer.toString(obj.x));
+      } else {
+        x = 456;
+      }
+    } catch (NullPointerException e) {
+    }
+    return x;
+  }
+
   private static void assertEquals(int expected, int actual) {
     if (expected != actual) {
       throw new AssertionError("Expected: " + expected + ", Actual: " + actual);
diff --git a/test/680-sink-regression/Android.bp b/test/680-sink-regression/Android.bp
deleted file mode 100644
index f55b8ae..0000000
--- a/test/680-sink-regression/Android.bp
+++ /dev/null
@@ -1,40 +0,0 @@
-// Generated by `regen-test-files`. Do not edit manually.
-
-// Build rules for ART run-test `680-sink-regression`.
-
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "art_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["art_license"],
-}
-
-// Test's Dex code.
-java_test {
-    name: "art-run-test-680-sink-regression",
-    defaults: ["art-run-test-defaults"],
-    test_config_template: ":art-run-test-target-template",
-    srcs: ["src/**/*.java"],
-    data: [
-        ":art-run-test-680-sink-regression-expected-stdout",
-        ":art-run-test-680-sink-regression-expected-stderr",
-    ],
-}
-
-// Test's expected standard output.
-genrule {
-    name: "art-run-test-680-sink-regression-expected-stdout",
-    out: ["art-run-test-680-sink-regression-expected-stdout.txt"],
-    srcs: ["expected-stdout.txt"],
-    cmd: "cp -f $(in) $(out)",
-}
-
-// Test's expected standard error.
-genrule {
-    name: "art-run-test-680-sink-regression-expected-stderr",
-    out: ["art-run-test-680-sink-regression-expected-stderr.txt"],
-    srcs: ["expected-stderr.txt"],
-    cmd: "cp -f $(in) $(out)",
-}
diff --git a/test/680-sink-regression/expected-stderr.txt b/test/680-sink-regression/expected-stderr.txt
deleted file mode 100644
index e69de29..0000000
--- a/test/680-sink-regression/expected-stderr.txt
+++ /dev/null
diff --git a/test/680-sink-regression/expected-stdout.txt b/test/680-sink-regression/expected-stdout.txt
deleted file mode 100644
index b0aad4d..0000000
--- a/test/680-sink-regression/expected-stdout.txt
+++ /dev/null
@@ -1 +0,0 @@
-passed
diff --git a/test/680-sink-regression/info.txt b/test/680-sink-regression/info.txt
deleted file mode 100644
index 547e3b8..0000000
--- a/test/680-sink-regression/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Regression test for code sinking with exceptions (b/75971227).
diff --git a/test/680-sink-regression/src/Main.java b/test/680-sink-regression/src/Main.java
deleted file mode 100644
index 642c3ab..0000000
--- a/test/680-sink-regression/src/Main.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.*;
-
-/**
- * Regression test for b/75971227 (code sinking with exceptions).
- */
-public class Main {
-
-  public static class N {
-    int x;
-  }
-
-  private int f;
-
-  public int doit(N n1) throws FileNotFoundException {
-    int x = 1;
-    N n3 = new N();
-    try {
-      if (n1.x == 0) {
-        f = 11;
-        x = 3;
-      } else {
-        f = x;
-      }
-      throw new FileNotFoundException("n3" + n3.x);
-    } catch (NullPointerException e) {
-    }
-    return x;
-  }
-
-
-  public static void main(String[] args) {
-    N n = new N();
-    Main t = new Main();
-    int x = 0;
-
-    // Main 1, null pointer argument.
-    t.f = 0;
-    try {
-      x = t.doit(null);
-    } catch (FileNotFoundException e) {
-      x = -1;
-    }
-    if (x != 1 || t.f != 0) {
-      throw new Error("Main 1: x=" + x + " f=" + t.f);
-    }
-
-    // Main 2, n.x is 0.
-    n.x = 0;
-    try {
-      x = t.doit(n);
-    } catch (FileNotFoundException e) {
-      x = -1;
-    }
-    if (x != -1 || t.f != 11) {
-      throw new Error("Main 2: x=" + x + " f=" + t.f);
-    }
-
-    // Main 3, n.x is not 0.
-    n.x = 1;
-    try {
-      x = t.doit(n);
-    } catch (FileNotFoundException e) {
-      x = -1;
-    }
-    if (x != -1 || t.f != 1) {
-      throw new Error("Main 3: x=" + x + " f=" + t.f);
-    }
-
-    System.out.println("passed");
-  }
-}