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