1 /*
2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import jdk.incubator.code.CodeReflection;
25 import java.util.function.Supplier;
26
27
28 /*
29 * @test
30 * @summary Smoke test for code reflection with null constants.
31 * @modules jdk.incubator.code
32 * @enablePreview
33 * @build NullTest
34 * @build CodeReflectionTester
35 * @run main CodeReflectionTester NullTest
36 */
37
38 public class NullTest {
39
40 @CodeReflection
41 @IR("""
42 func @"test1" (%0 : java.type:"NullTest")java.type:"void" -> {
43 %1 : java.type:"java.lang.String" = constant @null;
44 %2 : Var<java.type:"java.lang.String"> = var %1 @"s";
45 return;
46 };
47 """)
48 void test1() {
49 String s = null;
50 }
51
52 @CodeReflection
53 @IR("""
54 func @"test2" (%0 : java.type:"NullTest")java.type:"void" -> {
55 %1 : java.type:"java.lang.Object" = constant @null;
56 %2 : java.type:"java.lang.String" = cast %1 @java.type:"java.lang.String";
57 %3 : Var<java.type:"java.lang.String"> = var %2 @"s";
58 return;
59 };
60 """)
61 void test2() {
62 String s = (String)null;
63 }
64
65 @CodeReflection
66 @IR("""
67 func @"test3" (%0 : java.type:"NullTest", %1 : java.type:"boolean")java.type:"java.lang.String" -> {
68 %2 : Var<java.type:"boolean"> = var %1 @"cond";
69 %3 : java.type:"java.lang.String" = java.cexpression
70 ()java.type:"boolean" -> {
71 %4 : java.type:"boolean" = var.load %2;
72 yield %4;
73 }
74 ()java.type:"java.lang.String" -> {
75 %5 : java.type:"java.lang.String" = constant @null;
76 yield %5;
77 }
78 ()java.type:"java.lang.String" -> {
79 %6 : java.type:"java.lang.String" = constant @"";
80 yield %6;
81 };
82 return %3;
83 };
84 """)
85 String test3(boolean cond) {
86 return cond ? null : "";
87 }
88
89 @CodeReflection
90 @IR("""
91 func @"test4" (%0 : java.type:"NullTest", %1 : java.type:"boolean")java.type:"java.lang.String" -> {
92 %2 : Var<java.type:"boolean"> = var %1 @"cond";
93 %3 : java.type:"java.lang.String" = java.cexpression
94 ()java.type:"boolean" -> {
95 %4 : java.type:"boolean" = var.load %2;
96 yield %4;
97 }
98 ()java.type:"java.lang.String" -> {
99 %5 : java.type:"java.lang.String" = constant @"";
100 yield %5;
101 }
102 ()java.type:"java.lang.String" -> {
103 %6 : java.type:"java.lang.String" = constant @null;
104 yield %6;
105 };
106 return %3;
107 };
108 """)
109 String test4(boolean cond) {
110 return cond ? "" : null;
111 }
112
113 @CodeReflection
114 @IR("""
115 func @"test5" (%0 : java.type:"NullTest", %1 : java.type:"boolean")java.type:"java.lang.String" -> {
116 %2 : Var<java.type:"boolean"> = var %1 @"cond";
117 %3 : java.type:"java.lang.String" = java.cexpression
118 ()java.type:"boolean" -> {
119 %4 : java.type:"boolean" = var.load %2;
120 yield %4;
121 }
122 ()java.type:"java.lang.String" -> {
123 %5 : java.type:"java.lang.String" = constant @null;
124 yield %5;
125 }
126 ()java.type:"java.lang.String" -> {
127 %6 : java.type:"java.lang.String" = constant @null;
128 yield %6;
129 };
130 return %3;
131 };
132 """)
133 String test5(boolean cond) {
134 return cond ? null : null;
135 }
136
137 @CodeReflection
138 @IR("""
139 func @"test6" (%0 : java.type:"NullTest", %1 : java.type:"boolean")java.type:"java.lang.String" -> {
140 %2 : Var<java.type:"boolean"> = var %1 @"cond";
141 %3 : java.type:"java.lang.Object" = java.cexpression
142 ()java.type:"boolean" -> {
143 %4 : java.type:"boolean" = var.load %2;
144 yield %4;
145 }
146 ()java.type:"java.lang.Object" -> {
147 %5 : java.type:"java.lang.Object" = constant @null;
148 yield %5;
149 }
150 ()java.type:"java.lang.Object" -> {
151 %6 : java.type:"java.lang.Object" = constant @null;
152 yield %6;
153 };
154 %7 : java.type:"java.lang.String" = cast %3 @java.type:"java.lang.String";
155 return %7;
156 };
157 """)
158 String test6(boolean cond) {
159 return (String)(cond ? null : null);
160 }
161
162 @CodeReflection
163 @IR("""
164 func @"test7" (%0 : java.type:"NullTest", %1 : java.type:"int")java.type:"java.lang.String" -> {
165 %2 : Var<java.type:"int"> = var %1 @"cond";
166 %3 : java.type:"int" = var.load %2;
167 %4 : java.type:"java.lang.String" = java.switch.expression %3
168 (%5 : java.type:"int")java.type:"boolean" -> {
169 %6 : java.type:"int" = constant @1;
170 %7 : java.type:"boolean" = eq %5 %6;
171 yield %7;
172 }
173 ()java.type:"java.lang.String" -> {
174 %8 : java.type:"java.lang.String" = constant @"";
175 yield %8;
176 }
177 ()java.type:"boolean" -> {
178 %9 : java.type:"boolean" = constant @true;
179 yield %9;
180 }
181 ()java.type:"java.lang.String" -> {
182 %10 : java.type:"java.lang.String" = constant @null;
183 yield %10;
184 };
185 return %4;
186 };
187 """)
188 String test7(int cond) {
189 return switch(cond) {
190 case 1 -> "";
191 default -> null;
192 };
193 }
194
195 @CodeReflection
196 @IR("""
197 func @"test8" (%0 : java.type:"NullTest", %1 : java.type:"int")java.type:"java.lang.String" -> {
198 %2 : Var<java.type:"int"> = var %1 @"cond";
199 %3 : java.type:"int" = var.load %2;
200 %4 : java.type:"java.lang.String" = java.switch.expression %3
201 (%5 : java.type:"int")java.type:"boolean" -> {
202 %6 : java.type:"int" = constant @1;
203 %7 : java.type:"boolean" = eq %5 %6;
204 yield %7;
205 }
206 ()java.type:"java.lang.String" -> {
207 %8 : java.type:"java.lang.String" = constant @null;
208 yield %8;
209 }
210 ()java.type:"boolean" -> {
211 %9 : java.type:"boolean" = constant @true;
212 yield %9;
213 }
214 ()java.type:"java.lang.String" -> {
215 %10 : java.type:"java.lang.String" = constant @"";
216 yield %10;
217 };
218 return %4;
219 };
220 """)
221 String test8(int cond) {
222 return switch(cond) {
223 case 1 -> null;
224 default -> "";
225 };
226 }
227
228 @CodeReflection
229 @IR("""
230 func @"test9" (%0 : java.type:"NullTest", %1 : java.type:"int")java.type:"java.lang.String" -> {
231 %2 : Var<java.type:"int"> = var %1 @"cond";
232 %3 : java.type:"int" = var.load %2;
233 %4 : java.type:"java.lang.String" = java.switch.expression %3
234 (%5 : java.type:"int")java.type:"boolean" -> {
235 %6 : java.type:"int" = constant @1;
236 %7 : java.type:"boolean" = eq %5 %6;
237 yield %7;
238 }
239 ()java.type:"java.lang.String" -> {
240 %8 : java.type:"java.lang.String" = constant @null;
241 yield %8;
242 }
243 ()java.type:"boolean" -> {
244 %9 : java.type:"boolean" = constant @true;
245 yield %9;
246 }
247 ()java.type:"java.lang.String" -> {
248 %10 : java.type:"java.lang.String" = constant @null;
249 yield %10;
250 };
251 return %4;
252 };
253 """)
254 String test9(int cond) {
255 return switch(cond) {
256 case 1 -> null;
257 default -> null;
258 };
259 }
260
261 @CodeReflection
262 @IR("""
263 func @"test10" (%0 : java.type:"NullTest", %1 : java.type:"int")java.type:"java.lang.String" -> {
264 %2 : Var<java.type:"int"> = var %1 @"cond";
265 %3 : java.type:"int" = var.load %2;
266 %4 : java.type:"java.lang.Object" = java.switch.expression %3
267 (%5 : java.type:"int")java.type:"boolean" -> {
268 %6 : java.type:"int" = constant @1;
269 %7 : java.type:"boolean" = eq %5 %6;
270 yield %7;
271 }
272 ()java.type:"java.lang.Object" -> {
273 %8 : java.type:"java.lang.Object" = constant @null;
274 yield %8;
275 }
276 ()java.type:"boolean" -> {
277 %9 : java.type:"boolean" = constant @true;
278 yield %9;
279 }
280 ()java.type:"java.lang.Object" -> {
281 %10 : java.type:"java.lang.Object" = constant @null;
282 yield %10;
283 };
284 %11 : java.type:"java.lang.String" = cast %4 @java.type:"java.lang.String";
285 return %11;
286 };
287 """)
288 String test10(int cond) {
289 return (String)switch(cond) {
290 case 1 -> null;
291 default -> null;
292 };
293 }
294
295 @CodeReflection
296 @IR("""
297 func @"test11" (%0 : java.type:"NullTest", %1 : java.type:"int")java.type:"java.lang.String" -> {
298 %2 : Var<java.type:"int"> = var %1 @"cond";
299 %3 : java.type:"int" = var.load %2;
300 %4 : java.type:"java.lang.String" = java.switch.expression %3
301 (%5 : java.type:"int")java.type:"boolean" -> {
302 %6 : java.type:"int" = constant @1;
303 %7 : java.type:"boolean" = eq %5 %6;
304 yield %7;
305 }
306 ()java.type:"java.lang.String" -> {
307 %8 : java.type:"java.lang.String" = constant @"";
308 java.yield %8;
309 }
310 ()java.type:"boolean" -> {
311 %9 : java.type:"boolean" = constant @true;
312 yield %9;
313 }
314 ()java.type:"java.lang.String" -> {
315 %10 : java.type:"java.lang.String" = constant @null;
316 java.yield %10;
317 };
318 return %4;
319 };
320 """)
321 String test11(int cond) {
322 return switch(cond) {
323 case 1 -> { yield ""; }
324 default -> { yield null; }
325 };
326 }
327
328 @CodeReflection
329 @IR("""
330 func @"test12" (%0 : java.type:"NullTest", %1 : java.type:"int")java.type:"java.lang.String" -> {
331 %2 : Var<java.type:"int"> = var %1 @"cond";
332 %3 : java.type:"int" = var.load %2;
333 %4 : java.type:"java.lang.String" = java.switch.expression %3
334 (%5 : java.type:"int")java.type:"boolean" -> {
335 %6 : java.type:"int" = constant @1;
336 %7 : java.type:"boolean" = eq %5 %6;
337 yield %7;
338 }
339 ()java.type:"java.lang.String" -> {
340 %8 : java.type:"java.lang.String" = constant @null;
341 java.yield %8;
342 }
343 ()java.type:"boolean" -> {
344 %9 : java.type:"boolean" = constant @true;
345 yield %9;
346 }
347 ()java.type:"java.lang.String" -> {
348 %10 : java.type:"java.lang.String" = constant @"";
349 java.yield %10;
350 };
351 return %4;
352 };
353 """)
354 String test12(int cond) {
355 return switch(cond) {
356 case 1 -> { yield null; }
357 default -> { yield ""; }
358 };
359 }
360
361 @CodeReflection
362 @IR("""
363 func @"test13" (%0 : java.type:"NullTest", %1 : java.type:"int")java.type:"java.lang.String" -> {
364 %2 : Var<java.type:"int"> = var %1 @"cond";
365 %3 : java.type:"int" = var.load %2;
366 %4 : java.type:"java.lang.String" = java.switch.expression %3
367 (%5 : java.type:"int")java.type:"boolean" -> {
368 %6 : java.type:"int" = constant @1;
369 %7 : java.type:"boolean" = eq %5 %6;
370 yield %7;
371 }
372 ()java.type:"java.lang.String" -> {
373 %8 : java.type:"java.lang.String" = constant @null;
374 java.yield %8;
375 }
376 ()java.type:"boolean" -> {
377 %9 : java.type:"boolean" = constant @true;
378 yield %9;
379 }
380 ()java.type:"java.lang.String" -> {
381 %10 : java.type:"java.lang.String" = constant @null;
382 java.yield %10;
383 };
384 return %4;
385 };
386 """)
387 String test13(int cond) {
388 return switch(cond) {
389 case 1 -> { yield null; }
390 default -> { yield null; }
391 };
392 }
393
394 @CodeReflection
395 @IR("""
396 func @"test14" (%0 : java.type:"NullTest", %1 : java.type:"int")java.type:"java.lang.String" -> {
397 %2 : Var<java.type:"int"> = var %1 @"cond";
398 %3 : java.type:"int" = var.load %2;
399 %4 : java.type:"java.lang.Object" = java.switch.expression %3
400 (%5 : java.type:"int")java.type:"boolean" -> {
401 %6 : java.type:"int" = constant @1;
402 %7 : java.type:"boolean" = eq %5 %6;
403 yield %7;
404 }
405 ()java.type:"java.lang.Object" -> {
406 %8 : java.type:"java.lang.Object" = constant @null;
407 java.yield %8;
408 }
409 ()java.type:"boolean" -> {
410 %9 : java.type:"boolean" = constant @true;
411 yield %9;
412 }
413 ()java.type:"java.lang.Object" -> {
414 %10 : java.type:"java.lang.Object" = constant @null;
415 java.yield %10;
416 };
417 %11 : java.type:"java.lang.String" = cast %4 @java.type:"java.lang.String";
418 return %11;
419 };
420 """)
421 String test14(int cond) {
422 return (String)switch(cond) {
423 case 1 -> { yield null; }
424 default -> { yield null; }
425 };
426 }
427
428 @CodeReflection
429 @IR("""
430 func @"test15" (%0 : java.type:"NullTest")java.type:"java.util.function.Supplier<java.lang.String>" -> {
431 %1 : java.type:"java.util.function.Supplier<java.lang.String>" = lambda ()java.type:"java.lang.String" -> {
432 %2 : java.type:"java.lang.String" = constant @null;
433 return %2;
434 };
435 return %1;
436 };
437 """)
438 Supplier<String> test15() {
439 return () -> null;
440 }
441
442 static void m(String s, String... ss) { }
443
444 @CodeReflection
445 @IR("""
446 func @"test16" (%0 : java.type:"NullTest")java.type:"void" -> {
447 %1 : java.type:"java.lang.String" = constant @null;
448 invoke %1 @java.ref:"NullTest::m(java.lang.String, java.lang.String[]):void" @invoke.kind="STATIC" @invoke.varargs=true;
449 return;
450 };
451 """)
452 void test16() {
453 m(null);
454 }
455
456 @CodeReflection
457 @IR("""
458 func @"test17" (%0 : java.type:"NullTest")java.type:"void" -> {
459 %1 : java.type:"java.lang.String" = constant @null;
460 %2 : java.type:"java.lang.String[]" = constant @null;
461 invoke %1 %2 @java.ref:"NullTest::m(java.lang.String, java.lang.String[]):void";
462 return;
463 };
464 """)
465 void test17() {
466 m(null, null);
467 }
468
469 @CodeReflection
470 @IR("""
471 func @"test18" (%0 : java.type:"NullTest")java.type:"void" -> {
472 %1 : java.type:"java.lang.String" = constant @null;
473 %2 : java.type:"java.lang.String" = constant @null;
474 %3 : java.type:"java.lang.String" = constant @null;
475 invoke %1 %2 %3 @java.ref:"NullTest::m(java.lang.String, java.lang.String[]):void" @invoke.kind="STATIC" @invoke.varargs=true;
476 return;
477 };
478 """)
479 void test18() {
480 m(null, null, null);
481 }
482
483 static class Box {
484 Box(String s, String... ss) { }
485 }
486
487 @CodeReflection
488 @IR("""
489 func @"test19" (%0 : java.type:"NullTest")java.type:"void" -> {
490 %1 : java.type:"java.lang.String" = constant @null;
491 %2 : java.type:"NullTest$Box" = new %1 @java.ref:"NullTest$Box::(java.lang.String, java.lang.String[])" @new.varargs=true;
492 return;
493 };
494 """)
495 void test19() {
496 new Box(null);
497 }
498
499 @CodeReflection
500 @IR("""
501 func @"test20" (%0 : java.type:"NullTest")java.type:"void" -> {
502 %1 : java.type:"java.lang.String" = constant @null;
503 %2 : java.type:"java.lang.String[]" = constant @null;
504 %3 : java.type:"NullTest$Box" = new %1 %2 @java.ref:"NullTest$Box::(java.lang.String, java.lang.String[])";
505 return;
506 };
507 """)
508 void test20() {
509 new Box(null, null);
510 }
511
512 @CodeReflection
513 @IR("""
514 func @"test21" (%0 : java.type:"NullTest")java.type:"void" -> {
515 %1 : java.type:"java.lang.String" = constant @null;
516 %2 : java.type:"java.lang.String" = constant @null;
517 %3 : java.type:"java.lang.String" = constant @null;
518 %4 : java.type:"NullTest$Box" = new %1 %2 %3 @java.ref:"NullTest$Box::(java.lang.String, java.lang.String[])" @new.varargs=true;
519 return;
520 };
521 """)
522 void test21() {
523 new Box(null, null, null);
524 }
525 }