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 : java.type:"ImplicitConversionTest")java.type:"void" -> {
 42                 %1 : java.type:"int" = constant @1;
 43                 %2 : java.type:"long" = conv %1;
 44                 %3 : Var<java.type:"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 : java.type:"ImplicitConversionTest")java.type:"void" -> {
 55                 %1 : Var<java.type:"long"> = var @"x";
 56                 %2 : java.type:"int" = constant @1;
 57                 %3 : java.type:"long" = conv %2;
 58                 var.store %1 %3;
 59                 return;
 60             };
 61             """)
 62     void test2() {
 63         long x;
 64         x = 1;
 65     }
 66 
 67     @CodeReflection
 68     @IR("""
 69             func @"test3" (%0 : java.type:"ImplicitConversionTest")java.type:"void" -> {
 70                 %1 : java.type:"long" = constant @0;
 71                 %2 : Var<java.type:"long"> = var %1 @"x";
 72                 %3 : java.type:"long" = var.load %2;
 73                 %4 : java.type:"int" = constant @1;
 74                 %5 : java.type:"long" = conv %4;
 75                 %6 : java.type:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"boolean")java.type:"void" -> {
 88                 %2 : Var<java.type:"boolean"> = var %1 @"cond";
 89                 %3 : Var<java.type:"long"> = var @"x";
 90                 %4 : java.type:"long" = java.cexpression
 91                     ()java.type:"boolean" -> {
 92                         %5 : java.type:"boolean" = var.load %2;
 93                         yield %5;
 94                     }
 95                     ()java.type:"long" -> {
 96                         %6 : java.type:"long" = constant @1;
 97                         yield %6;
 98                     }
 99                     ()java.type:"long" -> {
100                         %7 : java.type:"int" = constant @2;
101                         %8 : java.type:"long" = conv %7;
102                         yield %8;
103                     };
104                 var.store %3 %4;
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 : java.type:"ImplicitConversionTest", %1 : java.type:"boolean")java.type:"void" -> {
116                 %2 : Var<java.type:"boolean"> = var %1 @"cond";
117                 %3 : Var<java.type:"long"> = var @"x";
118                 %4 : java.type:"long" = java.cexpression
119                     ()java.type:"boolean" -> {
120                         %5 : java.type:"boolean" = var.load %2;
121                         yield %5;
122                     }
123                     ()java.type:"long" -> {
124                         %6 : java.type:"int" = constant @1;
125                         %7 : java.type:"long" = conv %6;
126                         yield %7;
127                     }
128                     ()java.type:"long" -> {
129                         %8 : java.type:"long" = constant @2;
130                         yield %8;
131                     };
132                 var.store %3 %4;
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 : java.type:"ImplicitConversionTest", %1 : java.type:"boolean")java.type:"void" -> {
144                 %2 : Var<java.type:"boolean"> = var %1 @"cond";
145                 %3 : Var<java.type:"long"> = var @"x";
146                 %4 : java.type:"int" = java.cexpression
147                     ()java.type:"boolean" -> {
148                         %5 : java.type:"boolean" = var.load %2;
149                         yield %5;
150                     }
151                     ()java.type:"int" -> {
152                         %6 : java.type:"int" = constant @1;
153                         yield %6;
154                     }
155                     ()java.type:"int" -> {
156                         %7 : java.type:"int" = constant @2;
157                         yield %7;
158                     };
159                 %8 : java.type:"long" = conv %4;
160                 var.store %3 %8;
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 : java.type:"ImplicitConversionTest")java.type:"long" -> {
172                 %1 : java.type:"int" = constant @1;
173                 %2 : java.type:"long" = conv %1;
174                 return %2;
175             };
176             """)
177     long test7() {
178         return 1;
179     }
180 
181     @CodeReflection
182     @IR("""
183             func @"test8" (%0 : java.type:"ImplicitConversionTest")java.type:"void" -> {
184                 %1 : java.type:"java.util.function.LongSupplier" = lambda ()java.type:"long" -> {
185                     %2 : java.type:"int" = constant @1;
186                     %3 : java.type:"long" = conv %2;
187                     return %3;
188                 };
189                 %4 : Var<java.type:"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 : java.type:"ImplicitConversionTest")java.type:"void" -> {
200                 %1 : java.type:"java.util.function.LongSupplier" = lambda ()java.type:"long" -> {
201                     %2 : java.type:"int" = constant @1;
202                     %3 : java.type:"long" = conv %2;
203                     return %3;
204                 };
205                 %4 : Var<java.type:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
216                 %2 : Var<java.type:"int"> = var %1 @"i";
217                 %3 : java.type:"int" = var.load %2;
218                 %4 : java.type:"long" = java.switch.expression %3
219                     (%5 : java.type:"int")java.type:"boolean" -> {
220                         %6 : java.type:"int" = constant @1;
221                         %7 : java.type:"boolean" = eq %5 %6;
222                         yield %7;
223                     }
224                     ()java.type:"long" -> {
225                         %8 : java.type:"long" = constant @1;
226                         yield %8;
227                     }
228                     ()java.type:"boolean" -> {
229                         %9 : java.type:"boolean" = constant @true;
230                         yield %9;
231                     }
232                     ()java.type:"long" -> {
233                         %10 : java.type:"int" = constant @0;
234                         %11 : java.type:"long" = conv %10;
235                         yield %11;
236                     };
237                 %12 : Var<java.type:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
251                 %2 : Var<java.type:"int"> = var %1 @"i";
252                 %3 : java.type:"int" = var.load %2;
253                 %4 : java.type:"long" = java.switch.expression %3
254                     (%5 : java.type:"int")java.type:"boolean" -> {
255                         %6 : java.type:"int" = constant @1;
256                         %7 : java.type:"boolean" = eq %5 %6;
257                         yield %7;
258                     }
259                     ()java.type:"long" -> {
260                         %8 : java.type:"int" = constant @1;
261                         %9 : java.type:"long" = conv %8;
262                         yield %9;
263                     }
264                     ()java.type:"boolean" -> {
265                         %10 : java.type:"boolean" = constant @true;
266                         yield %10;
267                     }
268                     ()java.type:"long" -> {
269                         %11 : java.type:"long" = constant @0;
270                         yield %11;
271                     };
272                 %12 : Var<java.type:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
286                 %2 : Var<java.type:"int"> = var %1 @"i";
287                 %3 : java.type:"int" = var.load %2;
288                 %4 : java.type:"long" = java.switch.expression %3
289                     (%5 : java.type:"int")java.type:"boolean" -> {
290                         %6 : java.type:"int" = constant @1;
291                         %7 : java.type:"boolean" = eq %5 %6;
292                         yield %7;
293                     }
294                     ()java.type:"long" -> {
295                         %8 : java.type:"int" = constant @1;
296                         %9 : java.type:"long" = conv %8;
297                         yield %9;
298                     }
299                     ()java.type:"boolean" -> {
300                         %10 : java.type:"boolean" = constant @true;
301                         yield %10;
302                     }
303                     ()java.type:"long" -> {
304                         %11 : java.type:"int" = constant @0;
305                         %12 : java.type:"long" = conv %11;
306                         yield %12;
307                     };
308                 %13 : Var<java.type:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
322                 %2 : Var<java.type:"int"> = var %1 @"i";
323                 %3 : java.type:"int" = var.load %2;
324                 %4 : java.type:"long" = java.switch.expression %3
325                     (%5 : java.type:"int")java.type:"boolean" -> {
326                         %6 : java.type:"int" = constant @1;
327                         %7 : java.type:"boolean" = eq %5 %6;
328                         yield %7;
329                     }
330                     ()java.type:"long" -> {
331                         %8 : java.type:"long" = constant @1;
332                         java.yield %8;
333                     }
334                     ()java.type:"boolean" -> {
335                         %9 : java.type:"boolean" = constant @true;
336                         yield %9;
337                     }
338                     ()java.type:"long" -> {
339                         %10 : java.type:"int" = constant @0;
340                         %11 : java.type:"long" = conv %10;
341                         java.yield %11;
342                     };
343                 %12 : Var<java.type:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
357                 %2 : Var<java.type:"int"> = var %1 @"i";
358                 %3 : java.type:"int" = var.load %2;
359                 %4 : java.type:"long" = java.switch.expression %3
360                     (%5 : java.type:"int")java.type:"boolean" -> {
361                         %6 : java.type:"int" = constant @1;
362                         %7 : java.type:"boolean" = eq %5 %6;
363                         yield %7;
364                     }
365                     ()java.type:"long" -> {
366                         %8 : java.type:"int" = constant @1;
367                         %9 : java.type:"long" = conv %8;
368                         java.yield %9;
369                     }
370                     ()java.type:"boolean" -> {
371                         %10 : java.type:"boolean" = constant @true;
372                         yield %10;
373                     }
374                     ()java.type:"long" -> {
375                         %11 : java.type:"long" = constant @0;
376                         java.yield %11;
377                     };
378                 %12 : Var<java.type:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
392                 %2 : Var<java.type:"int"> = var %1 @"i";
393                 %3 : java.type:"int" = var.load %2;
394                 %4 : java.type:"long" = java.switch.expression %3
395                     (%5 : java.type:"int")java.type:"boolean" -> {
396                         %6 : java.type:"int" = constant @1;
397                         %7 : java.type:"boolean" = eq %5 %6;
398                         yield %7;
399                     }
400                     ()java.type:"long" -> {
401                         %8 : java.type:"int" = constant @1;
402                         %9 : java.type:"long" = conv %8;
403                         java.yield %9;
404                     }
405                     ()java.type:"boolean" -> {
406                         %10 : java.type:"boolean" = constant @true;
407                         yield %10;
408                     }
409                     ()java.type:"long" -> {
410                         %11 : java.type:"int" = constant @0;
411                         %12 : java.type:"long" = conv %11;
412                         java.yield %12;
413                     };
414                 %13 : Var<java.type:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
428                 %2 : Var<java.type:"int"> = var %1 @"i";
429                 %3 : java.type:"int" = var.load %2;
430                 %4 : java.type:"long" = conv %3;
431                 %5 : java.type:"long" = constant @2;
432                 %6 : java.type:"long" = add %4 %5;
433                 %7 : Var<java.type:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
446                 %2 : Var<java.type:"int"> = var %1 @"i";
447                 %3 : java.type:"int" = var.load %2;
448                 %4 : java.type:"long" = conv %3;
449                 invoke %0 %4 @java.ref:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
462                 %2 : Var<java.type:"int"> = var %1 @"i";
463                 %3 : java.type:"int" = var.load %2;
464                 %4 : java.type:"int" = var.load %2;
465                 invoke %0 %3 %4 @java.ref:"ImplicitConversionTest::m(int, int, long[]):void" @invoke.kind="INSTANCE" @invoke.varargs=true;
466                 return;
467             };
468             """)
469     void test18(int i) {
470         m(i, i);
471     }
472 
473     @CodeReflection
474     @IR("""
475             func @"test19" (%0 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
476                 %2 : Var<java.type:"int"> = var %1 @"i";
477                 %3 : java.type:"int" = var.load %2;
478                 %4 : java.type:"int" = var.load %2;
479                 %5 : java.type:"int" = var.load %2;
480                 %6 : java.type:"long" = conv %5;
481                 invoke %0 %3 %4 %6 @java.ref:"ImplicitConversionTest::m(int, int, long[]):void" @invoke.kind="INSTANCE" @invoke.varargs=true;
482                 return;
483             };
484            """)
485     void test19(int i) {
486         m(i, i, i);
487     }
488 
489     @CodeReflection
490     @IR("""
491             func @"test20" (%0 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
492                 %2 : Var<java.type:"int"> = var %1 @"i";
493                 %3 : java.type:"int" = var.load %2;
494                 %4 : java.type:"int" = var.load %2;
495                 %5 : java.type:"int" = var.load %2;
496                 %6 : java.type:"long" = conv %5;
497                 %7 : java.type:"int" = var.load %2;
498                 %8 : java.type:"long" = conv %7;
499                 invoke %0 %3 %4 %6 %8 @java.ref:"ImplicitConversionTest::m(int, int, long[]):void" @invoke.kind="INSTANCE" @invoke.varargs=true;
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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
515                 %2 : Var<java.type:"int"> = var %1 @"i";
516                 %3 : java.type:"int" = var.load %2;
517                 %4 : java.type:"long" = conv %3;
518                 %5 : java.type:"ImplicitConversionTest$Box" = new %4 @java.ref:"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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
529                 %2 : Var<java.type:"int"> = var %1 @"i";
530                 %3 : java.type:"int" = var.load %2;
531                 %4 : java.type:"int" = var.load %2;
532                 %5 : java.type:"ImplicitConversionTest$Box" = new %3 %4 @java.ref:"ImplicitConversionTest$Box::(int, int, long[])" @new.varargs=true;
533                 return;
534             };
535             """)
536     void test22(int i) {
537         new Box(i, i);
538     }
539 
540     @CodeReflection
541     @IR("""
542             func @"test23" (%0 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
543                 %2 : Var<java.type:"int"> = var %1 @"i";
544                 %3 : java.type:"int" = var.load %2;
545                 %4 : java.type:"int" = var.load %2;
546                 %5 : java.type:"int" = var.load %2;
547                 %6 : java.type:"long" = conv %5;
548                 %7 : java.type:"ImplicitConversionTest$Box" = new %3 %4 %6 @java.ref:"ImplicitConversionTest$Box::(int, int, long[])" @new.varargs=true;
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 : java.type:"ImplicitConversionTest", %1 : java.type:"int")java.type:"void" -> {
559                 %2 : Var<java.type:"int"> = var %1 @"i";
560                 %3 : java.type:"int" = var.load %2;
561                 %4 : java.type:"int" = var.load %2;
562                 %5 : java.type:"int" = var.load %2;
563                 %6 : java.type:"long" = conv %5;
564                 %7 : java.type:"int" = var.load %2;
565                 %8 : java.type:"long" = conv %7;
566                 %9 : java.type:"ImplicitConversionTest$Box" = new %3 %4 %6 %8 @java.ref:"ImplicitConversionTest$Box::(int, int, long[])" @new.varargs=true;
567                 return;
568             };
569             """)
570     void test24(int i) {
571         new Box(i, i, i, i);
572     }
573 }