summaryrefslogtreecommitdiff
path: root/test/639-checker-code-sinking/src/Main.java
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2022-03-23 15:37:40 +0000
committer Santiago Aboy Solanes <solanes@google.com> 2022-03-29 09:50:09 +0000
commit26e70d86005d2f907edef5a4703d87aecbd42d57 (patch)
treeb2c249ae42f6227d4b5d4dc97eb72c5a3671dfba /test/639-checker-code-sinking/src/Main.java
parent7188478756e039d69e63b061fbef2472d96be449 (diff)
Allow code to sink right before the TryBoundary
Instructions before TryBoundary entry are not considered to be inside of a try. Therefore, we can allow to sink instructions at that level. Bug: 226143661 Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: If29a53cfd94e1d0a7afb79d0e9fb7e76b337c493
Diffstat (limited to 'test/639-checker-code-sinking/src/Main.java')
-rw-r--r--test/639-checker-code-sinking/src/Main.java101
1 files changed, 101 insertions, 0 deletions
diff --git a/test/639-checker-code-sinking/src/Main.java b/test/639-checker-code-sinking/src/Main.java
index bd50fa639f..4becc11845 100644
--- a/test/639-checker-code-sinking/src/Main.java
+++ b/test/639-checker-code-sinking/src/Main.java
@@ -396,6 +396,9 @@ public class Main {
assertEquals(456, testDoNotSinkToTry());
assertEquals(456, testDoNotSinkToCatchInsideTry());
assertEquals(456, testSinkWithinTryBlock());
+ assertEquals(456, testSinkRightBeforeTryBlock());
+ assertEquals(456, testSinkToSecondCatch());
+ assertEquals(456, testDoNotSinkToCatchInsideTryWithMoreThings(false, false));
}
/// CHECK-START: int Main.testSinkToCatchBlock() code_sinking (before)
@@ -510,6 +513,103 @@ public class Main {
return 456;
}
+ /// CHECK-START: int Main.testSinkRightBeforeTryBlock() code_sinking (before)
+ /// CHECK: <<ObjLoadClass:l\d+>> LoadClass class_name:java.lang.Object
+ /// CHECK: NewInstance [<<ObjLoadClass>>]
+ /// CHECK: If
+ /// CHECK: TryBoundary kind:entry
+
+ /// CHECK-START: int Main.testSinkRightBeforeTryBlock() code_sinking (after)
+ /// CHECK: If
+ /// CHECK: <<ObjLoadClass:l\d+>> LoadClass class_name:java.lang.Object
+ /// CHECK: NewInstance [<<ObjLoadClass>>]
+ /// CHECK: TryBoundary kind:entry
+ private static int testSinkRightBeforeTryBlock() {
+ Object o = new Object();
+ if (doEarlyReturn) {
+ try {
+ throw new Error(o.toString());
+ } catch (Error e) {
+ return 123;
+ }
+ }
+ return 456;
+ }
+
+ /// CHECK-START: int Main.testSinkToSecondCatch() code_sinking (before)
+ /// CHECK: <<ObjLoadClass:l\d+>> LoadClass class_name:java.lang.Object
+ /// CHECK: NewInstance [<<ObjLoadClass>>]
+ /// CHECK: TryBoundary kind:entry
+ /// CHECK: TryBoundary kind:entry
+
+ /// CHECK-START: int Main.testSinkToSecondCatch() code_sinking (after)
+ /// CHECK: TryBoundary kind:entry
+ /// CHECK: TryBoundary kind:entry
+ /// CHECK: <<ObjLoadClass:l\d+>> LoadClass class_name:java.lang.Object
+ /// CHECK: NewInstance [<<ObjLoadClass>>]
+
+ // Consistency check to make sure there's exactly two entry TryBoundary.
+ /// CHECK-START: int Main.testSinkToSecondCatch() code_sinking (after)
+ /// CHECK: TryBoundary kind:entry
+ /// CHECK: TryBoundary kind:entry
+ /// CHECK-NOT: TryBoundary kind:entry
+ private static int testSinkToSecondCatch() {
+ Object o = new Object();
+ try {
+ if (doEarlyReturn) {
+ return 123;
+ }
+ } catch (Error e) {
+ throw new Error();
+ }
+
+ try {
+ // We need a different boolean to the one above, so that the compiler cannot optimize this
+ // return away.
+ if (doOtherEarlyReturn) {
+ return 789;
+ }
+ } catch (Error e) {
+ throw new Error(o.toString());
+ }
+
+ return 456;
+ }
+
+ /// CHECK-START: int Main.testDoNotSinkToCatchInsideTryWithMoreThings(boolean, boolean) code_sinking (before)
+ /// CHECK-NOT: TryBoundary kind:entry
+ /// CHECK: <<ObjLoadClass:l\d+>> LoadClass class_name:java.lang.Object
+ /// CHECK: NewInstance [<<ObjLoadClass>>]
+
+ /// CHECK-START: int Main.testDoNotSinkToCatchInsideTryWithMoreThings(boolean, boolean) code_sinking (after)
+ /// CHECK-NOT: TryBoundary kind:entry
+ /// CHECK: <<ObjLoadClass:l\d+>> LoadClass class_name:java.lang.Object
+ /// CHECK: NewInstance [<<ObjLoadClass>>]
+
+ // Tests that we don't sink the Object creation into a catch handler surrounded by try/catch, even
+ // when that inner catch is not at the boundary of the outer try catch.
+ private static int testDoNotSinkToCatchInsideTryWithMoreThings(boolean a, boolean b) {
+ Object o = new Object();
+ try {
+ if (a) {
+ System.out.println(a);
+ }
+ try {
+ if (doEarlyReturn) {
+ return 123;
+ }
+ } catch (Error e) {
+ throw new Error(o.toString());
+ }
+ if (b) {
+ System.out.println(b);
+ }
+ } catch (Error e) {
+ throw new Error();
+ }
+ return 456;
+ }
+
private static void assertEquals(int expected, int actual) {
if (expected != actual) {
throw new AssertionError("Expected: " + expected + ", Actual: " + actual);
@@ -523,6 +623,7 @@ public class Main {
static boolean doThrow;
static boolean doLoop;
static boolean doEarlyReturn;
+ static boolean doOtherEarlyReturn;
static Main mainField = new Main();
static Object obj = new Object();
}