xref: /aosp_15_r20/art/test/673-checker-throw-vmethod/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker /**
18*795d594fSAndroid Build Coastguard Worker  * Tests for detecting throwing methods for code sinking.
19*795d594fSAndroid Build Coastguard Worker  */
20*795d594fSAndroid Build Coastguard Worker public class Main {
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker   //
23*795d594fSAndroid Build Coastguard Worker   // Some "runtime library" methods.
24*795d594fSAndroid Build Coastguard Worker   //
25*795d594fSAndroid Build Coastguard Worker 
doThrow(String par)26*795d594fSAndroid Build Coastguard Worker   public final void doThrow(String par) {
27*795d594fSAndroid Build Coastguard Worker     throw new Error("you are null: " + par);
28*795d594fSAndroid Build Coastguard Worker   }
29*795d594fSAndroid Build Coastguard Worker 
checkNotNullDirect(Object obj, String par)30*795d594fSAndroid Build Coastguard Worker   public final void checkNotNullDirect(Object obj, String par) {
31*795d594fSAndroid Build Coastguard Worker     if (obj == null)
32*795d594fSAndroid Build Coastguard Worker       throw new Error("you are null: " + par);
33*795d594fSAndroid Build Coastguard Worker   }
34*795d594fSAndroid Build Coastguard Worker 
checkNotNullSplit(Object obj, String par)35*795d594fSAndroid Build Coastguard Worker   public final void checkNotNullSplit(Object obj, String par) {
36*795d594fSAndroid Build Coastguard Worker     if (obj == null)
37*795d594fSAndroid Build Coastguard Worker       doThrow(par);
38*795d594fSAndroid Build Coastguard Worker   }
39*795d594fSAndroid Build Coastguard Worker 
40*795d594fSAndroid Build Coastguard Worker   //
41*795d594fSAndroid Build Coastguard Worker   // Various ways of enforcing non-null parameter.
42*795d594fSAndroid Build Coastguard Worker   // In all cases, par should be subject to code sinking.
43*795d594fSAndroid Build Coastguard Worker   //
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doit1(int[]) code_sinking (before)
46*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
47*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Str:l\d+>> LoadString
48*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Tst:z\d+>> Equal
49*795d594fSAndroid Build Coastguard Worker   /// CHECK:                If [<<Tst>>]
50*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
51*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
52*795d594fSAndroid Build Coastguard Worker   /// CHECK:                InvokeStaticOrDirect [{{l\d+}},<<Str>>] method_name:java.lang.StringBuilder.append
53*795d594fSAndroid Build Coastguard Worker   /// CHECK:                Throw
54*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
55*795d594fSAndroid Build Coastguard Worker   //
56*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doit1(int[]) code_sinking (after)
57*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
58*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Tst:z\d+>> Equal
59*795d594fSAndroid Build Coastguard Worker   /// CHECK:                If [<<Tst>>]
60*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
61*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
62*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Str:l\d+>> LoadString
63*795d594fSAndroid Build Coastguard Worker   /// CHECK:                InvokeStaticOrDirect [{{l\d+}},<<Str>>] method_name:java.lang.StringBuilder.append
64*795d594fSAndroid Build Coastguard Worker   /// CHECK:                Throw
65*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
doit1(int[] a)66*795d594fSAndroid Build Coastguard Worker   public void doit1(int[] a) {
67*795d594fSAndroid Build Coastguard Worker     // Being in the boot image means we know the load string cannot throw. Create one that is
68*795d594fSAndroid Build Coastguard Worker     // unlikely to be there to ensure we handle that case.
69*795d594fSAndroid Build Coastguard Worker     String par = "stringUnlikelyToBeInBootImage";
70*795d594fSAndroid Build Coastguard Worker     if (a == null)
71*795d594fSAndroid Build Coastguard Worker       throw new Error("you are null: " + par);
72*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
73*795d594fSAndroid Build Coastguard Worker       a[i] = 1;
74*795d594fSAndroid Build Coastguard Worker     }
75*795d594fSAndroid Build Coastguard Worker   }
76*795d594fSAndroid Build Coastguard Worker 
77*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doit2(int[]) code_sinking (before)
78*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
79*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Str:l\d+>> LoadString
80*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Tst:z\d+>> NotEqual
81*795d594fSAndroid Build Coastguard Worker   /// CHECK:                If [<<Tst>>]
82*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
83*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
84*795d594fSAndroid Build Coastguard Worker   /// CHECK:                InvokeStaticOrDirect [{{l\d+}},<<Str>>] method_name:Main.doThrow
85*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
86*795d594fSAndroid Build Coastguard Worker   //
87*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doit2(int[]) code_sinking (after)
88*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
89*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Tst:z\d+>> NotEqual
90*795d594fSAndroid Build Coastguard Worker   /// CHECK:                If [<<Tst>>]
91*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
92*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
93*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Str:l\d+>> LoadString
94*795d594fSAndroid Build Coastguard Worker   /// CHECK:                InvokeStaticOrDirect [{{l\d+}},<<Str>>] method_name:Main.doThrow
95*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
doit2(int[] a)96*795d594fSAndroid Build Coastguard Worker   public void doit2(int[] a) {
97*795d594fSAndroid Build Coastguard Worker     // Being in the boot image means we know the load string cannot throw. Create one that is
98*795d594fSAndroid Build Coastguard Worker     // unlikely to be there to ensure we handle that case.
99*795d594fSAndroid Build Coastguard Worker     String par = "stringUnlikelyToBeInBootImage";
100*795d594fSAndroid Build Coastguard Worker     if (a == null)
101*795d594fSAndroid Build Coastguard Worker       doThrow(par);
102*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
103*795d594fSAndroid Build Coastguard Worker       a[i] = 2;
104*795d594fSAndroid Build Coastguard Worker     }
105*795d594fSAndroid Build Coastguard Worker   }
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doit3(int[]) code_sinking (before)
108*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
109*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Str:l\d+>> LoadString
110*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Tst:z\d+>> Equal
111*795d594fSAndroid Build Coastguard Worker   /// CHECK:                If [<<Tst>>]
112*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
113*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
114*795d594fSAndroid Build Coastguard Worker   /// CHECK:                InvokeStaticOrDirect [{{l\d+}},<<Str>>] method_name:java.lang.StringBuilder.append
115*795d594fSAndroid Build Coastguard Worker   /// CHECK:                Throw
116*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
117*795d594fSAndroid Build Coastguard Worker   //
118*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doit3(int[]) code_sinking (after)
119*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
120*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Tst:z\d+>> Equal
121*795d594fSAndroid Build Coastguard Worker   /// CHECK:                If [<<Tst>>]
122*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
123*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
124*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Str:l\d+>> LoadString
125*795d594fSAndroid Build Coastguard Worker   /// CHECK:                InvokeStaticOrDirect [{{l\d+}},<<Str>>] method_name:java.lang.StringBuilder.append
126*795d594fSAndroid Build Coastguard Worker   /// CHECK:                Throw
127*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
doit3(int[] a)128*795d594fSAndroid Build Coastguard Worker   public void doit3(int[] a) {
129*795d594fSAndroid Build Coastguard Worker     // Being in the boot image means we know the load string cannot throw. Create one that is
130*795d594fSAndroid Build Coastguard Worker     // unlikely to be there to ensure we handle that case.
131*795d594fSAndroid Build Coastguard Worker     String par = "stringUnlikelyToBeInBootImage";
132*795d594fSAndroid Build Coastguard Worker     checkNotNullDirect(a, par);
133*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
134*795d594fSAndroid Build Coastguard Worker       a[i] = 3;
135*795d594fSAndroid Build Coastguard Worker     }
136*795d594fSAndroid Build Coastguard Worker   }
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doit4(int[]) code_sinking (before)
139*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
140*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Str:l\d+>> LoadString
141*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Tst:z\d+>> NotEqual
142*795d594fSAndroid Build Coastguard Worker   /// CHECK:                If [<<Tst>>]
143*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
144*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
145*795d594fSAndroid Build Coastguard Worker   /// CHECK:                InvokeStaticOrDirect [{{l\d+}},<<Str>>] method_name:Main.doThrow
146*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
147*795d594fSAndroid Build Coastguard Worker   //
148*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.doit4(int[]) code_sinking (after)
149*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
150*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Tst:z\d+>> NotEqual
151*795d594fSAndroid Build Coastguard Worker   /// CHECK:                If [<<Tst>>]
152*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
153*795d594fSAndroid Build Coastguard Worker   /// CHECK: begin_block
154*795d594fSAndroid Build Coastguard Worker   /// CHECK:   <<Str:l\d+>> LoadString
155*795d594fSAndroid Build Coastguard Worker   /// CHECK:                InvokeStaticOrDirect [{{l\d+}},<<Str>>] method_name:Main.doThrow
156*795d594fSAndroid Build Coastguard Worker   /// CHECK: end_block
doit4(int[] a)157*795d594fSAndroid Build Coastguard Worker   public void doit4(int[] a) {
158*795d594fSAndroid Build Coastguard Worker     // Being in the boot image means we know the load string cannot throw. Create one that is
159*795d594fSAndroid Build Coastguard Worker     // unlikely to be there to ensure we handle that case.
160*795d594fSAndroid Build Coastguard Worker     String par = "stringUnlikelyToBeInBootImage";
161*795d594fSAndroid Build Coastguard Worker     checkNotNullSplit(a, par);
162*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < a.length; i++) {
163*795d594fSAndroid Build Coastguard Worker       a[i] = 4;
164*795d594fSAndroid Build Coastguard Worker     }
165*795d594fSAndroid Build Coastguard Worker   }
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker   //
168*795d594fSAndroid Build Coastguard Worker   // Test driver.
169*795d594fSAndroid Build Coastguard Worker   //
170*795d594fSAndroid Build Coastguard Worker 
main(String[] args)171*795d594fSAndroid Build Coastguard Worker   static public void main(String[] args) {
172*795d594fSAndroid Build Coastguard Worker     int[] a = new int[100];
173*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 100; i++) {
174*795d594fSAndroid Build Coastguard Worker       a[i] = 0;
175*795d594fSAndroid Build Coastguard Worker     }
176*795d594fSAndroid Build Coastguard Worker 
177*795d594fSAndroid Build Coastguard Worker     Main m = new Main();
178*795d594fSAndroid Build Coastguard Worker 
179*795d594fSAndroid Build Coastguard Worker     try {
180*795d594fSAndroid Build Coastguard Worker       m.doit1(null);
181*795d594fSAndroid Build Coastguard Worker       System.out.println("should not reach this!");
182*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
183*795d594fSAndroid Build Coastguard Worker       m.doit1(a);
184*795d594fSAndroid Build Coastguard Worker     }
185*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 100; i++) {
186*795d594fSAndroid Build Coastguard Worker       expectEquals(1, a[i]);
187*795d594fSAndroid Build Coastguard Worker     }
188*795d594fSAndroid Build Coastguard Worker 
189*795d594fSAndroid Build Coastguard Worker     try {
190*795d594fSAndroid Build Coastguard Worker       m.doit2(null);
191*795d594fSAndroid Build Coastguard Worker       System.out.println("should not reach this!");
192*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
193*795d594fSAndroid Build Coastguard Worker       m.doit2(a);
194*795d594fSAndroid Build Coastguard Worker     }
195*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 100; i++) {
196*795d594fSAndroid Build Coastguard Worker       expectEquals(2, a[i]);
197*795d594fSAndroid Build Coastguard Worker     }
198*795d594fSAndroid Build Coastguard Worker 
199*795d594fSAndroid Build Coastguard Worker     try {
200*795d594fSAndroid Build Coastguard Worker       m.doit3(null);
201*795d594fSAndroid Build Coastguard Worker       System.out.println("should not reach this!");
202*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
203*795d594fSAndroid Build Coastguard Worker       m.doit3(a);
204*795d594fSAndroid Build Coastguard Worker     }
205*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 100; i++) {
206*795d594fSAndroid Build Coastguard Worker       expectEquals(3, a[i]);
207*795d594fSAndroid Build Coastguard Worker     }
208*795d594fSAndroid Build Coastguard Worker 
209*795d594fSAndroid Build Coastguard Worker     try {
210*795d594fSAndroid Build Coastguard Worker       m.doit4(null);
211*795d594fSAndroid Build Coastguard Worker       System.out.println("should not reach this!");
212*795d594fSAndroid Build Coastguard Worker     } catch (Error e) {
213*795d594fSAndroid Build Coastguard Worker       m.doit4(a);
214*795d594fSAndroid Build Coastguard Worker     }
215*795d594fSAndroid Build Coastguard Worker     for (int i = 0; i < 100; i++) {
216*795d594fSAndroid Build Coastguard Worker       expectEquals(4, a[i]);
217*795d594fSAndroid Build Coastguard Worker     }
218*795d594fSAndroid Build Coastguard Worker 
219*795d594fSAndroid Build Coastguard Worker     System.out.println("passed");
220*795d594fSAndroid Build Coastguard Worker   }
221*795d594fSAndroid Build Coastguard Worker 
expectEquals(int expected, int result)222*795d594fSAndroid Build Coastguard Worker   private static void expectEquals(int expected, int result) {
223*795d594fSAndroid Build Coastguard Worker     if (expected != result) {
224*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected: " + expected + ", found: " + result);
225*795d594fSAndroid Build Coastguard Worker     }
226*795d594fSAndroid Build Coastguard Worker   }
227*795d594fSAndroid Build Coastguard Worker }
228