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