blob: 2eac6c92a505b650b57acb17196597cb4e308980 [file] [log] [blame]
Guillaume Sanchez222862c2015-06-09 18:33:02 +01001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17public class Main {
18 public static boolean $inline$classTypeTest(Object o) {
19 return o instanceof SubMain;
20 }
21
22 public static boolean $inline$interfaceTypeTest(Object o) {
23 return o instanceof Itf;
24 }
25
26 public static SubMain subMain;
27 public static Main mainField;
28 public static Unrelated unrelatedField;
29 public static FinalUnrelated finalUnrelatedField;
30
31 /// CHECK-START: boolean Main.classTypeTestNull() register (after)
32 /// CHECK-DAG: <<Const:i\d+>> IntConstant 0
33 /// CHECK-DAG: Return [<<Const>>]
34 public static boolean classTypeTestNull() {
35 return $inline$classTypeTest(null);
36 }
37
38 /// CHECK-START: boolean Main.classTypeTestExactMain() register (after)
39 /// CHECK-DAG: <<Const:i\d+>> IntConstant 0
40 /// CHECK-DAG: Return [<<Const>>]
41 public static boolean classTypeTestExactMain() {
42 return $inline$classTypeTest(new Main());
43 }
44
45 /// CHECK-START: boolean Main.classTypeTestExactSubMain() register (after)
46 /// CHECK-DAG: <<Const:i\d+>> IntConstant 1
47 /// CHECK-DAG: Return [<<Const>>]
48 public static boolean classTypeTestExactSubMain() {
49 return $inline$classTypeTest(new SubMain());
50 }
51
52 /// CHECK-START: boolean Main.classTypeTestSubMainOrNull() register (after)
53 /// CHECK-DAG: <<Value:z\d+>> NotEqual
54 /// CHECK-DAG: Return [<<Value>>]
55 public static boolean classTypeTestSubMainOrNull() {
56 return $inline$classTypeTest(subMain);
57 }
58
59 /// CHECK-START: boolean Main.classTypeTestMainOrNull() register (after)
60 /// CHECK-DAG: <<Value:z\d+>> InstanceOf
61 /// CHECK-DAG: Return [<<Value>>]
62 public static boolean classTypeTestMainOrNull() {
63 return $inline$classTypeTest(mainField);
64 }
65
66 /// CHECK-START: boolean Main.classTypeTestUnrelated() register (after)
67 /// CHECK-DAG: <<Const:i\d+>> IntConstant 0
68 /// CHECK-DAG: Return [<<Const>>]
69 public static boolean classTypeTestUnrelated() {
70 return $inline$classTypeTest(unrelatedField);
71 }
72
73 /// CHECK-START: boolean Main.classTypeTestFinalUnrelated() register (after)
74 /// CHECK-DAG: <<Const:i\d+>> IntConstant 0
75 /// CHECK-DAG: Return [<<Const>>]
76 public static boolean classTypeTestFinalUnrelated() {
77 return $inline$classTypeTest(finalUnrelatedField);
78 }
79
80 /// CHECK-START: boolean Main.interfaceTypeTestNull() register (after)
81 /// CHECK-DAG: <<Const:i\d+>> IntConstant 0
82 /// CHECK-DAG: Return [<<Const>>]
83 public static boolean interfaceTypeTestNull() {
84 return $inline$interfaceTypeTest(null);
85 }
86
87 /// CHECK-START: boolean Main.interfaceTypeTestExactMain() register (after)
88 /// CHECK-DAG: <<Const:i\d+>> IntConstant 0
89 /// CHECK-DAG: Return [<<Const>>]
90 public static boolean interfaceTypeTestExactMain() {
91 return $inline$interfaceTypeTest(new Main());
92 }
93
94 /// CHECK-START: boolean Main.interfaceTypeTestExactSubMain() register (after)
95 /// CHECK-DAG: <<Const:i\d+>> IntConstant 1
96 /// CHECK-DAG: Return [<<Const>>]
97 public static boolean interfaceTypeTestExactSubMain() {
98 return $inline$interfaceTypeTest(new SubMain());
99 }
100
101 /// CHECK-START: boolean Main.interfaceTypeTestSubMainOrNull() register (after)
102 /// CHECK-DAG: <<Value:z\d+>> NotEqual
103 /// CHECK-DAG: Return [<<Value>>]
104 public static boolean interfaceTypeTestSubMainOrNull() {
105 return $inline$interfaceTypeTest(subMain);
106 }
107
108 /// CHECK-START: boolean Main.interfaceTypeTestMainOrNull() register (after)
109 /// CHECK-DAG: <<Value:z\d+>> InstanceOf
110 /// CHECK-DAG: Return [<<Value>>]
111 public static boolean interfaceTypeTestMainOrNull() {
112 return $inline$interfaceTypeTest(mainField);
113 }
114
115 /// CHECK-START: boolean Main.interfaceTypeTestUnrelated() register (after)
116 /// CHECK-DAG: <<Value:z\d+>> InstanceOf
117 /// CHECK-DAG: Return [<<Value>>]
118 public static boolean interfaceTypeTestUnrelated() {
119 // This method is the main difference between doing an instanceof on an interface
120 // or a class. We have to keep the instanceof in case a subclass of Unrelated
121 // implements the interface.
122 return $inline$interfaceTypeTest(unrelatedField);
123 }
124
125 /// CHECK-START: boolean Main.interfaceTypeTestFinalUnrelated() register (after)
126 /// CHECK-DAG: <<Const:i\d+>> IntConstant 0
127 /// CHECK-DAG: Return [<<Const>>]
128 public static boolean interfaceTypeTestFinalUnrelated() {
129 return $inline$interfaceTypeTest(finalUnrelatedField);
130 }
131
Nicolas Geoffrayefa84682015-08-12 18:28:14 -0700132 // Check that we remove the LoadClass instruction from the graph.
133 /// CHECK-START: boolean Main.knownTestWithLoadedClass() register (after)
134 /// CHECK-NOT: LoadClass
135 public static boolean knownTestWithLoadedClass() {
136 return new String() instanceof String;
137 }
138
139 // Check that we do not remove the LoadClass instruction from the graph.
140 /// CHECK-START: boolean Main.knownTestWithUnloadedClass() register (after)
141 /// CHECK: <<Const:i\d+>> IntConstant 0
142 /// CHECK: LoadClass
143 /// CHECK: Return [<<Const>>]
144 public static boolean knownTestWithUnloadedClass() {
145 return $inline$returnMain() instanceof String;
146 }
147
148 public static Object $inline$returnMain() {
149 return new Main();
150 }
151
Guillaume Sanchez222862c2015-06-09 18:33:02 +0100152 public static void expect(boolean expected, boolean actual) {
153 if (expected != actual) {
154 throw new Error("Unexpected result");
155 }
156 }
157
158 public static void main(String[] args) {
159 expect(false, classTypeTestNull());
160 expect(false, classTypeTestExactMain());
161 expect(true, classTypeTestExactSubMain());
162
163 subMain = null;
164 expect(false, classTypeTestSubMainOrNull());
165 subMain = new SubMain();
166 expect(true, classTypeTestSubMainOrNull());
167
168 mainField = null;
169 expect(false, classTypeTestMainOrNull());
170 mainField = new Main();
171 expect(false, classTypeTestMainOrNull());
172 mainField = new SubMain();
173 expect(true, classTypeTestMainOrNull());
174
175 unrelatedField = null;
176 expect(false, classTypeTestUnrelated());
177 unrelatedField = new Unrelated();
178 expect(false, classTypeTestUnrelated());
179
180 finalUnrelatedField = null;
181 expect(false, classTypeTestFinalUnrelated());
182 finalUnrelatedField = new FinalUnrelated();
183 expect(false, classTypeTestFinalUnrelated());
184
185 expect(false, interfaceTypeTestNull());
186 expect(false, interfaceTypeTestExactMain());
187 expect(true, interfaceTypeTestExactSubMain());
188
189 subMain = null;
190 expect(false, interfaceTypeTestSubMainOrNull());
191 subMain = new SubMain();
192 expect(true, interfaceTypeTestSubMainOrNull());
193
194 mainField = null;
195 expect(false, interfaceTypeTestMainOrNull());
196 mainField = new Main();
197 expect(false, interfaceTypeTestMainOrNull());
198 mainField = new SubMain();
199 expect(true, interfaceTypeTestMainOrNull());
200
201 unrelatedField = null;
202 expect(false, interfaceTypeTestUnrelated());
203 unrelatedField = new Unrelated();
204 expect(false, interfaceTypeTestUnrelated());
205
206 finalUnrelatedField = null;
207 expect(false, interfaceTypeTestFinalUnrelated());
208 finalUnrelatedField = new FinalUnrelated();
209 expect(false, interfaceTypeTestFinalUnrelated());
210 }
211}
212
213interface Itf {
214}
215
216class SubMain extends Main implements Itf {
217}
218
219class Unrelated {
220}
221
222final class FinalUnrelated {
223}