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