xref: /aosp_15_r20/art/test/586-checker-null-array-get/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2016 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 import java.lang.reflect.Method;
18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationTargetException;
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker class Test1 {
21*795d594fSAndroid Build Coastguard Worker   int[] iarr;
22*795d594fSAndroid Build Coastguard Worker }
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker class Test2 {
25*795d594fSAndroid Build Coastguard Worker   float[] farr;
26*795d594fSAndroid Build Coastguard Worker }
27*795d594fSAndroid Build Coastguard Worker 
28*795d594fSAndroid Build Coastguard Worker public class Main {
getObjectArray()29*795d594fSAndroid Build Coastguard Worker   public static Object[] getObjectArray() { return null; }
getLongArray()30*795d594fSAndroid Build Coastguard Worker   public static long[] getLongArray() { return null; }
getNull()31*795d594fSAndroid Build Coastguard Worker   public static Object getNull() { return null; }
getNullTest1()32*795d594fSAndroid Build Coastguard Worker   public static Test1 getNullTest1() { return null; }
getNullTest2()33*795d594fSAndroid Build Coastguard Worker   public static Test2 getNullTest2() { return null; }
34*795d594fSAndroid Build Coastguard Worker 
$noinline$runSmaliTest(String name)35*795d594fSAndroid Build Coastguard Worker   public static void $noinline$runSmaliTest(String name) throws Throwable {
36*795d594fSAndroid Build Coastguard Worker     try {
37*795d594fSAndroid Build Coastguard Worker       Class<?> c = Class.forName("SmaliTests");
38*795d594fSAndroid Build Coastguard Worker       Method m = c.getMethod(name);
39*795d594fSAndroid Build Coastguard Worker       m.invoke(null);
40*795d594fSAndroid Build Coastguard Worker     } catch (InvocationTargetException ex) {
41*795d594fSAndroid Build Coastguard Worker       throw ex.getCause(); // re-raise expected exception.
42*795d594fSAndroid Build Coastguard Worker     } catch (Exception ex) {
43*795d594fSAndroid Build Coastguard Worker       throw new Error(ex);
44*795d594fSAndroid Build Coastguard Worker     }
45*795d594fSAndroid Build Coastguard Worker   }
46*795d594fSAndroid Build Coastguard Worker 
main(String[] args)47*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) {
48*795d594fSAndroid Build Coastguard Worker     try {
49*795d594fSAndroid Build Coastguard Worker       foo();
50*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected NullPointerException");
51*795d594fSAndroid Build Coastguard Worker     } catch (NullPointerException e) {
52*795d594fSAndroid Build Coastguard Worker       // Expected.
53*795d594fSAndroid Build Coastguard Worker     }
54*795d594fSAndroid Build Coastguard Worker     try {
55*795d594fSAndroid Build Coastguard Worker       bar();
56*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected NullPointerException");
57*795d594fSAndroid Build Coastguard Worker     } catch (NullPointerException e) {
58*795d594fSAndroid Build Coastguard Worker       // Expected.
59*795d594fSAndroid Build Coastguard Worker     }
60*795d594fSAndroid Build Coastguard Worker     try {
61*795d594fSAndroid Build Coastguard Worker       $noinline$runSmaliTest("bar");
62*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected NullPointerException");
63*795d594fSAndroid Build Coastguard Worker     } catch (NullPointerException e) {
64*795d594fSAndroid Build Coastguard Worker       // Expected.
65*795d594fSAndroid Build Coastguard Worker     } catch (Throwable t) {
66*795d594fSAndroid Build Coastguard Worker       throw new Error("Unexpected Throwable", t);
67*795d594fSAndroid Build Coastguard Worker     }
68*795d594fSAndroid Build Coastguard Worker     try {
69*795d594fSAndroid Build Coastguard Worker       $noinline$runSmaliTest("bar2");
70*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected NullPointerException");
71*795d594fSAndroid Build Coastguard Worker     } catch (NullPointerException e) {
72*795d594fSAndroid Build Coastguard Worker       // Expected.
73*795d594fSAndroid Build Coastguard Worker     } catch (Throwable t) {
74*795d594fSAndroid Build Coastguard Worker       throw new Error("Unexpected Throwable", t);
75*795d594fSAndroid Build Coastguard Worker     }
76*795d594fSAndroid Build Coastguard Worker 
77*795d594fSAndroid Build Coastguard Worker     try {
78*795d594fSAndroid Build Coastguard Worker       test1();
79*795d594fSAndroid Build Coastguard Worker       throw new Error("Expected NullPointerException");
80*795d594fSAndroid Build Coastguard Worker     } catch (NullPointerException e) {
81*795d594fSAndroid Build Coastguard Worker       // Expected.
82*795d594fSAndroid Build Coastguard Worker     }
83*795d594fSAndroid Build Coastguard Worker   }
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.foo() load_store_elimination (after)
86*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Null:l\d+>>   NullConstant
87*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Check:l\d+>>  NullCheck [<<Null>>]
88*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Get1:j\d+>>   ArrayGet [<<Check>>,{{i\d+}}]
89*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Get2:l\d+>>   ArrayGet [<<Check>>,{{i\d+}}]
foo()90*795d594fSAndroid Build Coastguard Worker   public static void foo() {
91*795d594fSAndroid Build Coastguard Worker     longField = getLongArray()[0];
92*795d594fSAndroid Build Coastguard Worker     objectField = getObjectArray()[0];
93*795d594fSAndroid Build Coastguard Worker   }
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: void Main.bar() load_store_elimination (after)
96*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Null:l\d+>>       NullConstant
97*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                     BoundType [<<Null>>]
98*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<CheckL:l\d+>>     NullCheck
99*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<GetL0:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
100*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<GetL1:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
101*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<GetL2:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
102*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<GetL3:l\d+>>      ArrayGet [<<CheckL>>,{{i\d+}}]
103*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<CheckJ:l\d+>>     NullCheck [<<Null>>]
104*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<GetJ0:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
105*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<GetJ1:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
106*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<GetJ2:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
107*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<GetJ3:j\d+>>      ArrayGet [<<CheckJ>>,{{i\d+}}]
bar()108*795d594fSAndroid Build Coastguard Worker   public static void bar() {
109*795d594fSAndroid Build Coastguard Worker     // We create multiple accesses that will lead the bounds check
110*795d594fSAndroid Build Coastguard Worker     // elimination pass to add a HDeoptimize. Not having the bounds check
111*795d594fSAndroid Build Coastguard Worker     // makes the ArrayGets look almost the same if it were not for the type!
112*795d594fSAndroid Build Coastguard Worker     String[] array = (String[])getNull();
113*795d594fSAndroid Build Coastguard Worker     objectField = array[0];
114*795d594fSAndroid Build Coastguard Worker     objectField = array[1];
115*795d594fSAndroid Build Coastguard Worker     objectField = array[2];
116*795d594fSAndroid Build Coastguard Worker     objectField = array[3];
117*795d594fSAndroid Build Coastguard Worker     long[] longArray = getLongArray();
118*795d594fSAndroid Build Coastguard Worker     longField = longArray[0];
119*795d594fSAndroid Build Coastguard Worker     longField = longArray[1];
120*795d594fSAndroid Build Coastguard Worker     longField = longArray[2];
121*795d594fSAndroid Build Coastguard Worker     longField = longArray[3];
122*795d594fSAndroid Build Coastguard Worker   }
123*795d594fSAndroid Build Coastguard Worker 
124*795d594fSAndroid Build Coastguard Worker   /// CHECK-START: float Main.test1() load_store_elimination (after)
125*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Null:l\d+>>       NullConstant
126*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Check1:l\d+>>     NullCheck [<<Null>>]
127*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<FieldGet1:l\d+>>  InstanceFieldGet [<<Check1>>] field_name:Test1.iarr
128*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<Check2:l\d+>>     NullCheck [<<FieldGet1>>]
129*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<ArrayGet1:i\d+>>  ArrayGet [<<Check2>>,{{i\d+}}]
130*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG: <<ArrayGet2:f\d+>>  ArrayGet [<<Check2>>,{{i\d+}}]
131*795d594fSAndroid Build Coastguard Worker   /// CHECK-DAG:                     Return [<<ArrayGet2>>]
test1()132*795d594fSAndroid Build Coastguard Worker   public static float test1() {
133*795d594fSAndroid Build Coastguard Worker     Test1 test1 = getNullTest1();
134*795d594fSAndroid Build Coastguard Worker     Test2 test2 = getNullTest2();
135*795d594fSAndroid Build Coastguard Worker     int[] iarr = test1.iarr;
136*795d594fSAndroid Build Coastguard Worker     float[] farr = test2.farr;
137*795d594fSAndroid Build Coastguard Worker     iarr[0] = iarr[1];
138*795d594fSAndroid Build Coastguard Worker     return farr[0];
139*795d594fSAndroid Build Coastguard Worker   }
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker   public static long longField;
142*795d594fSAndroid Build Coastguard Worker   public static Object objectField;
143*795d594fSAndroid Build Coastguard Worker }
144