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 java.lang.runtime.CodeReflection;
 25 import java.util.function.LongSupplier;
 26 
 27 
 28 /*
 29  * @test
 30  * @summary Smoke test for code reflection with implicit conversions.
 31  * @enablePreview
 32  * @build ImplicitConversionTest
 33  * @build CodeReflectionTester
 34  * @run main CodeReflectionTester ImplicitConversionTest
 35  */
 36 
 37 public class ImplicitConversionTest {
 38     @CodeReflection
 39     @IR("""
 40             func @"test1" (%0: ImplicitConversionTest)void -> {
 41                 %1 : int = constant @"1";
 42                 %2 : long = conv %1;
 43                 %3 : Var<long> = var %2 @"x";
 44                 return;
 45             };
 46             """)
 47     void test1() {
 48         long x = 1;
 49     }
 50 
 51     @CodeReflection
 52     @IR("""
 53             func @"test2" (%0: ImplicitConversionTest)void -> {
 54                 %1 : long = constant @"0";
 55                 %2 : Var<long> = var %1 @"x";
 56                 %3 : int = constant @"1";
 57                 %4 : long = conv %3;
 58                 var.store %2 %4;
 59                 return;
 60             };
 61             """)
 62     void test2() {
 63         long x;
 64         x = 1;
 65     }
 66 
 67     @CodeReflection
 68     @IR("""
 69             func @"test3" (%0: ImplicitConversionTest)void -> {
 70                 %1 : long = constant @"0";
 71                 %2 : Var<long> = var %1 @"x";
 72                 %3 : long = var.load %2;
 73                 %4 : int = constant @"1";
 74                 %5 : long = conv %4;
 75                 %6 : long = add %3 %5;
 76                 var.store %2 %6;
 77                 return;
 78             };
 79             """)
 80     void test3() {
 81         long x = 0L;
 82         x += 1;
 83     }
 84 
 85     @CodeReflection
 86     @IR("""
 87             func @"test4" (%0: ImplicitConversionTest, %1 : boolean)void -> {
 88                 %2 : Var<boolean> = var %1 @"cond";
 89                 %3 : long = constant @"0";
 90                 %4 : Var<long> = var %3 @"x";
 91                 %5 : long = java.cexpression
 92                     ^cond()boolean -> {
 93                         %6 : boolean = var.load %2;
 94                         yield %6;
 95                     }
 96                     ^truepart()long -> {
 97                         %7 : long = constant @"1";
 98                         yield %7;
 99                     }
100                     ^falsepart()long -> {
101                         %8 : int = constant @"2";
102                         %9 : long = conv %8;
103                         yield %9;
104                     };
105                 var.store %4 %5;
106                 return;
107             };
108             """)
109     void test4(boolean cond) {
110         long x;
111         x = cond ? 1L : 2;
112     }
113 
114     @CodeReflection
115     @IR("""
116            func @"test5" (%0: ImplicitConversionTest, %1 : boolean)void -> {
117                %2 : Var<boolean> = var %1 @"cond";
118                %3 : long = constant @"0";
119                %4 : Var<long> = var %3 @"x";
120                %5 : long = java.cexpression
121                    ^cond()boolean -> {
122                        %6 : boolean = var.load %2;
123                        yield %6;
124                    }
125                    ^truepart()long -> {
126                        %7 : int = constant @"1";
127                        %8 : long = conv %7;
128                        yield %8;
129                    }
130                    ^falsepart()long -> {
131                        %9 : long = constant @"2";
132                        yield %9;
133                    };
134                var.store %4 %5;
135                return;
136            };
137            """)
138     void test5(boolean cond) {
139         long x;
140         x = cond ? 1 : 2L;
141     }
142 
143     @CodeReflection
144     @IR("""
145            func @"test6" (%0: ImplicitConversionTest, %1 : boolean)void -> {
146                %2 : Var<boolean> = var %1 @"cond";
147                %3 : long = constant @"0";
148                %4 : Var<long> = var %3 @"x";
149                %5 : int = java.cexpression
150                    ^cond()boolean -> {
151                        %6 : boolean = var.load %2;
152                        yield %6;
153                    }
154                    ^truepart()int -> {
155                        %7 : int = constant @"1";
156                        yield %7;
157                    }
158                    ^falsepart()int -> {
159                        %8 : int = constant @"2";
160                        yield %8;
161                    };
162                %9 : long = conv %5;
163                var.store %4 %9;
164                return;
165            };
166            """)
167     void test6(boolean cond) {
168         long x;
169         x = cond ? 1 : 2;
170     }
171 
172     @CodeReflection
173     @IR("""
174             func @"test7" (%0: ImplicitConversionTest)long -> {
175                 %1 : int = constant @"1";
176                 %2 : long = conv %1;
177                 return %2;
178             };
179             """)
180     long test7() {
181         return 1;
182     }
183 
184     @CodeReflection
185     @IR("""
186             func @"test8" (%0: ImplicitConversionTest)void -> {
187                 %1 : java.util.function.LongSupplier = lambda ()long -> {
188                     %2 : int = constant @"1";
189                     %3 : long = conv %2;
190                     return %3;
191                 };
192                 %4 : Var<java.util.function.LongSupplier> = var %1 @"s";
193                 return;
194             };
195             """)
196     void test8() {
197         LongSupplier s = () -> { return 1; };
198     }
199 
200     @CodeReflection
201     @IR("""
202             func @"test9" (%0: ImplicitConversionTest)void -> {
203                 %1 : java.util.function.LongSupplier = lambda ()long -> {
204                     %2 : int = constant @"1";
205                     %3 : long = conv %2;
206                     return %3;
207                 };
208                 %4 : Var<java.util.function.LongSupplier> = var %1 @"s";
209                 return;
210             };
211             """)
212     void test9() {
213         LongSupplier s = () -> 1;
214     }
215 
216     @CodeReflection
217     @IR("""
218             func @"test10" (%0: ImplicitConversionTest, %1 : int)void -> {
219                 %2 : Var<int> = var %1 @"i";
220                 %3 : int = var.load %2;
221                 %4 : long = java.switch.expression %3
222                     ^constantCaseLabel(%5 : int)boolean -> {
223                         %6 : int = constant @"1";
224                         %7 : boolean = eq %5 %6;
225                         yield %7;
226                     }
227                     ()long -> {
228                         %8 : long = constant @"1";
229                         yield %8;
230                     }
231                     ^defaultCaseLabel()void -> {
232                         yield;
233                     }
234                     ()long -> {
235                         %9 : int = constant @"0";
236                         %10 : long = conv %9;
237                         yield %10;
238                     };
239                 %11 : Var<long> = var %4 @"l";
240                 return;
241             };
242             """)
243     void test10(int i) {
244         long l = switch (i) {
245             case 1 -> 1L;
246             default -> 0;
247         };
248     }
249 
250     @CodeReflection
251     @IR("""
252             func @"test11" (%0: ImplicitConversionTest, %1 : int)void -> {
253                 %2 : Var<int> = var %1 @"i";
254                 %3 : int = var.load %2;
255                 %4 : long = java.switch.expression %3
256                     ^constantCaseLabel(%5 : int)boolean -> {
257                         %6 : int = constant @"1";
258                         %7 : boolean = eq %5 %6;
259                         yield %7;
260                     }
261                     ()long -> {
262                         %8 : int = constant @"1";
263                         %9 : long = conv %8;
264                         yield %9;
265                     }
266                     ^defaultCaseLabel()void -> {
267                         yield;
268                     }
269                     ()long -> {
270                         %10 : long = constant @"0";
271                         yield %10;
272                     };
273                 %11 : Var<long> = var %4 @"l";
274                 return;
275             };
276             """)
277     void test11(int i) {
278         long l = switch (i) {
279             case 1 -> 1;
280             default -> 0L;
281         };
282     }
283 
284     @CodeReflection
285     @IR("""
286             func @"test12" (%0: ImplicitConversionTest, %1 : int)void -> {
287                 %2 : Var<int> = var %1 @"i";
288                 %3 : int = var.load %2;
289                 %4 : long = java.switch.expression %3
290                     ^constantCaseLabel(%5 : int)boolean -> {
291                         %6 : int = constant @"1";
292                         %7 : boolean = eq %5 %6;
293                         yield %7;
294                     }
295                     ()long -> {
296                         %8 : int = constant @"1";
297                         %9 : long = conv %8;
298                         yield %9;
299                     }
300                     ^defaultCaseLabel()void -> {
301                         yield;
302                     }
303                     ()long -> {
304                         %10 : int = constant @"0";
305                         %11 : long = conv %10;
306                         yield %11;
307                     };
308                 %12 : Var<long> = var %4 @"l";
309                 return;
310             };
311             """)
312     void test12(int i) {
313         long l = switch (i) {
314             case 1 -> 1;
315             default -> 0;
316         };
317     }
318 
319     @CodeReflection
320     @IR("""
321             func @"test13" (%0 : ImplicitConversionTest, %1 : int)void -> {
322                 %2 : Var<int> = var %1 @"i";
323                 %3 : int = var.load %2;
324                 %4 : long = java.switch.expression %3
325                     ^constantCaseLabel(%5 : int)boolean -> {
326                         %6 : int = constant @"1";
327                         %7 : boolean = eq %5 %6;
328                         yield %7;
329                     }
330                     ()long -> {
331                         %8 : long = constant @"1";
332                         java.yield %8;
333                     }
334                     ^defaultCaseLabel()void -> {
335                         yield;
336                     }
337                     ()long -> {
338                         %9 : int = constant @"0";
339                         %10 : long = conv %9;
340                         java.yield %10;
341                     };
342                 %11 : Var<long> = var %4 @"l";
343                 return;
344             };
345             """)
346     void test13(int i) {
347         long l = switch (i) {
348             case 1 -> { yield 1L; }
349             default -> { yield 0; }
350         };
351     }
352 
353     @CodeReflection
354     @IR("""
355             func @"test14" (%0 : ImplicitConversionTest, %1 : int)void -> {
356                 %2 : Var<int> = var %1 @"i";
357                 %3 : int = var.load %2;
358                 %4 : long = java.switch.expression %3
359                     ^constantCaseLabel(%5 : int)boolean -> {
360                         %6 : int = constant @"1";
361                         %7 : boolean = eq %5 %6;
362                         yield %7;
363                     }
364                     ()long -> {
365                         %8 : int = constant @"1";
366                         %9 : long = conv %8;
367                         java.yield %9;
368                     }
369                     ^defaultCaseLabel()void -> {
370                         yield;
371                     }
372                     ()long -> {
373                         %10 : long = constant @"0";
374                         java.yield %10;
375                     };
376                 %11 : Var<long> = var %4 @"l";
377                 return;
378             };
379             """)
380     void test14(int i) {
381         long l = switch (i) {
382             case 1 -> { yield 1; }
383             default -> { yield 0L; }
384         };
385     }
386 
387     @CodeReflection
388     @IR("""
389             func @"test15" (%0 : ImplicitConversionTest, %1 : int)void -> {
390                 %2 : Var<int> = var %1 @"i";
391                 %3 : int = var.load %2;
392                 %4 : long = java.switch.expression %3
393                     ^constantCaseLabel(%5 : int)boolean -> {
394                         %6 : int = constant @"1";
395                         %7 : boolean = eq %5 %6;
396                         yield %7;
397                     }
398                     ()long -> {
399                         %8 : int = constant @"1";
400                         %9 : long = conv %8;
401                         java.yield %9;
402                     }
403                     ^defaultCaseLabel()void -> {
404                         yield;
405                     }
406                     ()long -> {
407                         %10 : int = constant @"0";
408                         %11 : long = conv %10;
409                         java.yield %11;
410                     };
411                 %12 : Var<long> = var %4 @"l";
412                 return;
413             };
414             """)
415     void test15(int i) {
416         long l = switch (i) {
417             case 1 -> { yield 1; }
418             default -> { yield 0; }
419         };
420     }
421 
422     @CodeReflection
423     @IR("""
424             func @"test16" (%0: ImplicitConversionTest, %1 : int)void -> {
425                 %2 : Var<int> = var %1 @"i";
426                 %3 : int = var.load %2;
427                 %4 : long = conv %3;
428                 %5 : long = constant @"2";
429                 %6 : long = add %4 %5;
430                 %7 : Var<long> = var %6 @"l";
431                 return;
432             };
433             """)
434     void test16(int i) {
435         long l = i + 2L;
436     }
437 
438     void m(long l) { }
439 
440     @CodeReflection
441     @IR("""
442             func @"test17" (%0: ImplicitConversionTest, %1 : int)void -> {
443                 %2 : Var<int> = var %1 @"i";
444                 %3 : int = var.load %2;
445                 %4 : long = conv %3;
446                 invoke %0 %4 @"ImplicitConversionTest::m(long)void";
447                 return;
448             };
449             """)
450     void test17(int i) {
451         m(i);
452     }
453 
454     void m(int i1, int i2, long... l) { }
455 
456     @CodeReflection
457     @IR("""
458             func @"test18" (%0: ImplicitConversionTest, %1 : int)void -> {
459                 %2 : Var<int> = var %1 @"i";
460                 %3 : int = var.load %2;
461                 %4 : int = var.load %2;
462                 invoke %0 %3 %4 @"ImplicitConversionTest::m(int, int, long[])void";
463                 return;
464             };
465             """)
466     void test18(int i) {
467         m(i, i);
468     }
469 
470     @CodeReflection
471     @IR("""
472            func @"test19" (%0: ImplicitConversionTest, %1 : int)void -> {
473                 %2 : Var<int> = var %1 @"i";
474                 %3 : int = var.load %2;
475                 %4 : int = var.load %2;
476                 %5 : int = var.load %2;
477                 %6 : long = conv %5;
478                 invoke %0 %3 %4 %6 @"ImplicitConversionTest::m(int, int, long[])void";
479                 return;
480            };
481            """)
482     void test19(int i) {
483         m(i, i, i);
484     }
485 
486     @CodeReflection
487     @IR("""
488             func @"test20" (%0: ImplicitConversionTest, %1 : int)void -> {
489                 %2 : Var<int> = var %1 @"i";
490                 %3 : int = var.load %2;
491                 %4 : int = var.load %2;
492                 %5 : int = var.load %2;
493                 %6 : long = conv %5;
494                 %7 : int = var.load %2;
495                 %8 : long = conv %7;
496                 invoke %0 %3 %4 %6 %8 @"ImplicitConversionTest::m(int, int, long[])void";
497                 return;
498             };
499             """)
500     void test20(int i) {
501         m(i, i, i, i);
502     }
503 
504     static class Box {
505         Box(long l) { }
506         Box(int i1, int i2, long... longs) { }
507     }
508 
509     @CodeReflection
510     @IR("""
511             func @"test21" (%0: ImplicitConversionTest, %1 : int)void -> {
512                 %2 : Var<int> = var %1 @"i";
513                 %3 : int = var.load %2;
514                 %4 : long = conv %3;
515                 %5 : ImplicitConversionTest$Box = new %4 @"func<ImplicitConversionTest$Box, long>";
516                 return;
517             };
518             """)
519     void test21(int i) {
520         new Box(i);
521     }
522 
523     @CodeReflection
524     @IR("""
525             func @"test22" (%0: ImplicitConversionTest, %1 : int)void -> {
526                 %2 : Var<int> = var %1 @"i";
527                 %3 : int = var.load %2;
528                 %4 : int = var.load %2;
529                 %5 : ImplicitConversionTest$Box = new %3 %4 @"func<ImplicitConversionTest$Box, int, int, long[]>";
530                 return;
531             };
532             """)
533     void test22(int i) {
534         new Box(i, i);
535     }
536 
537     @CodeReflection
538     @IR("""
539            func @"test23" (%0 : ImplicitConversionTest, %1 : int)void -> {
540                %2 : Var<int> = var %1 @"i";
541                %3 : int = var.load %2;
542                %4 : int = var.load %2;
543                %5 : int = var.load %2;
544                %6 : long = conv %5;
545                %7 : ImplicitConversionTest$Box = new %3 %4 %6 @"func<ImplicitConversionTest$Box, int, int, long[]>";
546                return;
547            };
548            """)
549     void test23(int i) {
550         new Box(i, i, i);
551     }
552 
553     @CodeReflection
554     @IR("""
555             func @"test24" (%0 : ImplicitConversionTest, %1 : int)void -> {
556                 %2 : Var<int> = var %1 @"i";
557                 %3 : int = var.load %2;
558                 %4 : int = var.load %2;
559                 %5 : int = var.load %2;
560                 %6 : long = conv %5;
561                 %7 : int = var.load %2;
562                 %8 : long = conv %7;
563                 %9 : ImplicitConversionTest$Box = new %3 %4 %6 %8 @"func<ImplicitConversionTest$Box, int, int, long[]>";
564                 return;
565             };
566             """)
567     void test24(int i) {
568         new Box(i, i, i, i);
569     }
570 }