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 }