1 /*
  2  * Copyright (c) 2024, 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.Reflect;
 25 import java.util.List;
 26 
 27 /*
 28  * @test
 29  * @summary Smoke test for code reflection with for loops.
 30  * @modules jdk.incubator.code
 31  * @build BreakContinueTest
 32  * @build CodeReflectionTester
 33  * @run main CodeReflectionTester BreakContinueTest
 34  */
 35 
 36 
 37 public class BreakContinueTest {
 38     @Reflect
 39     @IR("""
 40             func @"test1" (%0 : java.type:"BreakContinueTest")java.type:"void" -> {
 41                 java.for
 42                     ()Var<java.type:"int"> -> {
 43                         %1 : java.type:"int" = constant @0;
 44                         %2 : Var<java.type:"int"> = var %1 @"i";
 45                         yield %2;
 46                     }
 47                     (%3 : Var<java.type:"int">)java.type:"boolean" -> {
 48                         %4 : java.type:"int" = var.load %3;
 49                         %5 : java.type:"int" = constant @10;
 50                         %6 : java.type:"boolean" = lt %4 %5;
 51                         yield %6;
 52                     }
 53                     (%7 : Var<java.type:"int">)java.type:"void" -> {
 54                         %8 : java.type:"int" = var.load %7;
 55                         %9 : java.type:"int" = constant @1;
 56                         %10 : java.type:"int" = add %8 %9;
 57                         var.store %7 %10;
 58                         yield;
 59                     }
 60                     (%11 : Var<java.type:"int">)java.type:"void" -> {
 61                         java.if
 62                             ()java.type:"boolean" -> {
 63                                 %12 : java.type:"boolean" = constant @true;
 64                                 yield %12;
 65                             }
 66                             ()java.type:"void" -> {
 67                                 java.continue;
 68                             };
 69                         java.if
 70                             ()java.type:"boolean" -> {
 71                                 %13 : java.type:"boolean" = constant @true;
 72                                 yield %13;
 73                             }
 74                             ()java.type:"void" -> {
 75                                 java.break;
 76                             };
 77                         java.for
 78                             ()Var<java.type:"int"> -> {
 79                                 %14 : java.type:"int" = constant @0;
 80                                 %15 : Var<java.type:"int"> = var %14 @"j";
 81                                 yield %15;
 82                             }
 83                             (%16 : Var<java.type:"int">)java.type:"boolean" -> {
 84                                 %17 : java.type:"int" = var.load %16;
 85                                 %18 : java.type:"int" = constant @10;
 86                                 %19 : java.type:"boolean" = lt %17 %18;
 87                                 yield %19;
 88                             }
 89                             (%20 : Var<java.type:"int">)java.type:"void" -> {
 90                                 %21 : java.type:"int" = var.load %20;
 91                                 %22 : java.type:"int" = constant @1;
 92                                 %23 : java.type:"int" = add %21 %22;
 93                                 var.store %20 %23;
 94                                 yield;
 95                             }
 96                             (%24 : Var<java.type:"int">)java.type:"void" -> {
 97                                 java.if
 98                                     ()java.type:"boolean" -> {
 99                                         %25 : java.type:"boolean" = constant @true;
100                                         yield %25;
101                                     }
102                                     ()java.type:"void" -> {
103                                         java.continue;
104                                     };
105                                 java.if
106                                     ()java.type:"boolean" -> {
107                                         %26 : java.type:"boolean" = constant @true;
108                                         yield %26;
109                                     }
110                                     ()java.type:"void" -> {
111                                         java.break;
112                                     };
113                                 java.continue;
114                             };
115                         java.continue;
116                     };
117                 return;
118             };
119             """)
120     void test1() {
121         for (int i = 0; i < 10; i++) {
122             if (true) {
123                 continue;
124             }
125             if (true) {
126                 break;
127             }
128             for (int j = 0; j < 10; j++) {
129                 if (true) {
130                     continue;
131                 }
132                 if (true) {
133                     break;
134                 }
135             }
136         }
137     }
138 
139     @Reflect
140     @IR("""
141             func @"test2" (%0 : java.type:"BreakContinueTest")java.type:"void" -> {
142                 java.labeled ()java.type:"void" -> {
143                     %1 : java.type:"java.lang.String" = constant @"outer";
144                     java.for
145                         ()Var<java.type:"int"> -> {
146                             %2 : java.type:"int" = constant @0;
147                             %3 : Var<java.type:"int"> = var %2 @"i";
148                             yield %3;
149                         }
150                         (%4 : Var<java.type:"int">)java.type:"boolean" -> {
151                             %5 : java.type:"int" = var.load %4;
152                             %6 : java.type:"int" = constant @10;
153                             %7 : java.type:"boolean" = lt %5 %6;
154                             yield %7;
155                         }
156                         (%8 : Var<java.type:"int">)java.type:"void" -> {
157                             %9 : java.type:"int" = var.load %8;
158                             %10 : java.type:"int" = constant @1;
159                             %11 : java.type:"int" = add %9 %10;
160                             var.store %8 %11;
161                             yield;
162                         }
163                         (%12 : Var<java.type:"int">)java.type:"void" -> {
164                             java.if
165                                 ()java.type:"boolean" -> {
166                                     %13 : java.type:"boolean" = constant @true;
167                                     yield %13;
168                                 }
169                                 ()java.type:"void" -> {
170                                     java.continue %1;
171                                 };
172                             java.if
173                                 ()java.type:"boolean" -> {
174                                     %14 : java.type:"boolean" = constant @true;
175                                     yield %14;
176                                 }
177                                 ()java.type:"void" -> {
178                                     java.break %1;
179                                 };
180                             java.labeled ()java.type:"void" -> {
181                                 %15 : java.type:"java.lang.String" = constant @"inner";
182                                 java.for
183                                     ()Var<java.type:"int"> -> {
184                                         %16 : java.type:"int" = constant @0;
185                                         %17 : Var<java.type:"int"> = var %16 @"j";
186                                         yield %17;
187                                     }
188                                     (%18 : Var<java.type:"int">)java.type:"boolean" -> {
189                                         %19 : java.type:"int" = var.load %18;
190                                         %20 : java.type:"int" = constant @10;
191                                         %21 : java.type:"boolean" = lt %19 %20;
192                                         yield %21;
193                                     }
194                                     (%22 : Var<java.type:"int">)java.type:"void" -> {
195                                         %23 : java.type:"int" = var.load %22;
196                                         %24 : java.type:"int" = constant @1;
197                                         %25 : java.type:"int" = add %23 %24;
198                                         var.store %22 %25;
199                                         yield;
200                                     }
201                                     (%26 : Var<java.type:"int">)java.type:"void" -> {
202                                         java.if
203                                             ()java.type:"boolean" -> {
204                                                 %27 : java.type:"boolean" = constant @true;
205                                                 yield %27;
206                                             }
207                                             ()java.type:"void" -> {
208                                                 java.continue;
209                                             };
210                                         java.if
211                                             ()java.type:"boolean" -> {
212                                                 %28 : java.type:"boolean" = constant @true;
213                                                 yield %28;
214                                             }
215                                             ()java.type:"void" -> {
216                                                 java.break;
217                                             };
218                                         java.if
219                                             ()java.type:"boolean" -> {
220                                                 %29 : java.type:"boolean" = constant @true;
221                                                 yield %29;
222                                             }
223                                             ()java.type:"void" -> {
224                                                 java.continue %1;
225                                             };
226                                         java.if
227                                             ()java.type:"boolean" -> {
228                                                 %30 : java.type:"boolean" = constant @true;
229                                                 yield %30;
230                                             }
231                                             ()java.type:"void" -> {
232                                                 java.break %1;
233                                             };
234                                         java.continue;
235                                     };
236                                 yield;
237                             };
238                             java.continue;
239                         };
240                     yield;
241                 };
242                 return;
243             };
244             """)
245     void test2() {
246         outer:
247         for (int i = 0; i < 10; i++) {
248             if (true) {
249                 continue outer;
250             }
251             if (true) {
252                 break outer;
253             }
254             inner:
255             for (int j = 0; j < 10; j++) {
256                 if (true) {
257                     continue;
258                 }
259                 if (true) {
260                     break;
261                 }
262                 if (true) {
263                     continue outer;
264                 }
265                 if (true) {
266                     break outer;
267                 }
268             }
269         }
270     }
271 
272     @Reflect
273     @IR("""
274             func @"test3" (%0 : java.type:"BreakContinueTest")java.type:"void" -> {
275                 java.labeled ()java.type:"void" -> {
276                     %1 : java.type:"java.lang.String" = constant @"b1";
277                     java.block ()java.type:"void" -> {
278                         java.labeled ()java.type:"void" -> {
279                             %2 : java.type:"java.lang.String" = constant @"b2";
280                             java.block ()java.type:"void" -> {
281                                 java.if
282                                     ()java.type:"boolean" -> {
283                                         %3 : java.type:"boolean" = constant @true;
284                                         yield %3;
285                                     }
286                                     ()java.type:"void" -> {
287                                         java.break %1;
288                                     };
289                                 java.if
290                                     ()java.type:"boolean" -> {
291                                         %4 : java.type:"boolean" = constant @true;
292                                         yield %4;
293                                     }
294                                     ()java.type:"void" -> {
295                                         java.break %2;
296                                     };
297                                 yield;
298                             };
299                             yield;
300                         };
301                         yield;
302                     };
303                     yield;
304                 };
305                 return;
306             };
307             """)
308     void test3() {
309         b1:
310         {
311             b2:
312             {
313                 if (true) {
314                     break b1;
315                 }
316                 if (true) {
317                     break b2;
318                 }
319             }
320         }
321     }
322 
323     @Reflect
324     @IR("""
325             func @"test4" (%0 : java.type:"BreakContinueTest")java.type:"void" -> {
326                 java.labeled ()java.type:"void" -> {
327                     %1 : java.type:"java.lang.String" = constant @"b";
328                     java.break %1;
329                 };
330                 %2 : java.type:"int" = constant @0;
331                 %3 : Var<java.type:"int"> = var %2 @"i";
332                 java.labeled ()java.type:"void" -> {
333                     %4 : java.type:"java.lang.String" = constant @"b";
334                     %5 : java.type:"int" = var.load %3;
335                     %6 : java.type:"int" = constant @1;
336                     %7 : java.type:"int" = add %5 %6;
337                     var.store %3 %7;
338                     yield;
339                 };
340                 java.labeled ()java.type:"void" -> {
341                     %8 : java.type:"java.lang.String" = constant @"a";
342                     java.labeled ()java.type:"void" -> {
343                         %9 : java.type:"java.lang.String" = constant @"b";
344                         java.block ()java.type:"void" -> {
345                             yield;
346                         };
347                         yield;
348                     };
349                     yield;
350                 };
351                 return;
352             };
353             """)
354     void test4() {
355         b:
356         break b;
357 
358         int i = 0;
359         b:
360         i++;
361 
362         a: b: {
363         }
364     }
365 }