1 /*
  2  * Copyright (c) 2025, 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.Quoted;
 25 import jdk.incubator.code.Reflect;
 26 import java.util.function.IntUnaryOperator;
 27 
 28 /*
 29  * @test
 30  * @summary Smoke test for code reflection with unreachable areas.
 31  * @modules jdk.incubator.code
 32  * @enablePreview
 33  * @build UnreachableTest
 34  * @build CodeReflectionTester
 35  * @run main CodeReflectionTester UnreachableTest
 36  */
 37 
 38 public class UnreachableTest {
 39 
 40     @Reflect
 41     @IR("""
 42             func @"test1" ()java.type:"void" -> {
 43                 java.block ()java.type:"void" -> {
 44                     return;
 45                 };
 46                 unreachable;
 47             };
 48             """)
 49     static void test1() {
 50         {
 51             return;
 52         }
 53     }
 54 
 55     @Reflect
 56     @IR("""
 57             func @"test2" (%0 : java.type:"int")java.type:"int" -> {
 58                 %1 : Var<java.type:"int"> = var %0 @"i";
 59                 java.block ()java.type:"void" -> {
 60                     %2 : java.type:"int" = var.load %1;
 61                     return %2;
 62                 };
 63                 unreachable;
 64             };
 65             """)
 66     static int test2(int i) {
 67         {
 68             return i;
 69         }
 70     }
 71 
 72     @Reflect
 73     @IR("""
 74             func @"test3" (%0 : java.type:"int")java.type:"int" -> {
 75                 %1 : Var<java.type:"int"> = var %0 @"i";
 76                 java.if
 77                     ()java.type:"boolean" -> {
 78                         %2 : java.type:"boolean" = constant @true;
 79                         yield %2;
 80                     }
 81                     ()java.type:"void" -> {
 82                         %3 : java.type:"int" = var.load %1;
 83                         return %3;
 84                     }
 85                     ()java.type:"void" -> {
 86                         %4 : java.type:"int" = var.load %1;
 87                         return %4;
 88                     };
 89                 unreachable;
 90             };
 91             """)
 92     static int test3(int i) {
 93         if (true) {
 94             return i;
 95         } else {
 96             return i;
 97         }
 98     }
 99 
100 
101     @Reflect
102     @IR("""
103             func @"test4" ()java.type:"void" -> {
104                 %0 : java.type:"java.util.function.IntUnaryOperator" = lambda @lambda.isQuotable=true (%1 : java.type:"int")java.type:"int" -> {
105                     %2 : Var<java.type:"int"> = var %1 @"i";
106                     java.if
107                         ()java.type:"boolean" -> {
108                             %3 : java.type:"boolean" = constant @true;
109                             yield %3;
110                         }
111                         ()java.type:"void" -> {
112                             %4 : java.type:"int" = var.load %2;
113                             return %4;
114                         }
115                         ()java.type:"void" -> {
116                             %5 : java.type:"int" = var.load %2;
117                             return %5;
118                         };
119                     unreachable;
120                 };
121                 %6 : Var<java.type:"java.util.function.IntUnaryOperator"> = var %0 @"f";
122                 return;
123             };
124             """)
125     static void test4() {
126         IntUnaryOperator f = (int i) -> {
127             if (true) {
128                 return i;
129             } else {
130                 return i;
131             }
132         };
133     }
134 
135     @Reflect
136     @IR("""
137             func @"test5" (%0 : java.type:"int")java.type:"void" -> {
138                 %1 : Var<java.type:"int"> = var %0 @"n";
139                 %2 : java.type:"int" = var.load %1;
140                 %3 : java.type:"java.lang.String" = java.switch.expression %2
141                     (%4 : java.type:"int")java.type:"boolean" -> {
142                         %5 : java.type:"int" = constant @42;
143                         %6 : java.type:"boolean" = eq %4 %5;
144                         yield %6;
145                     }
146                     ()java.type:"java.lang.String" -> {
147                         java.while
148                             ()java.type:"boolean" -> {
149                                 %7 : java.type:"boolean" = constant @true;
150                                 yield %7;
151                             }
152                             ()java.type:"void" -> {
153                                 java.continue;
154                             };
155                         unreachable;
156                     }
157                     ()java.type:"boolean" -> {
158                         %8 : java.type:"boolean" = constant @true;
159                         yield %8;
160                     }
161                     ()java.type:"java.lang.String" -> {
162                         %9 : java.type:"java.lang.String" = constant @"";
163                         yield %9;
164                     };
165                 %10 : Var<java.type:"java.lang.String"> = var %3 @"s";
166                 return;
167             };
168             """)
169     static void test5(int n) {
170         String s = switch (n) {
171             case 42 -> { while (true); }
172             default -> "";
173         };
174     }
175 
176     @IR("""
177             func @"f" ()java.type:"void" -> {
178                 %0 : java.type:"java.util.function.IntUnaryOperator" = lambda @lambda.isQuotable=true (%1 : java.type:"int")java.type:"int" -> {
179                     %2 : Var<java.type:"int"> = var %1 @"i";
180                     java.if
181                         ()java.type:"boolean" -> {
182                             %3 : java.type:"boolean" = constant @true;
183                             yield %3;
184                         }
185                         ()java.type:"void" -> {
186                             %4 : java.type:"int" = var.load %2;
187                             return %4;
188                         }
189                         ()java.type:"void" -> {
190                             %5 : java.type:"int" = var.load %2;
191                             return %5;
192                         };
193                     unreachable;
194                 };
195                 return;
196             };
197             """)
198     static final IntUnaryOperator QUOTABLE_TEST = (@Reflect IntUnaryOperator) (int i) -> {
199         if (true) {
200             return i;
201         } else {
202             return i;
203         }
204     };
205 }