xref: /llvm-project/clang/test/AST/ByteCode/loops.cpp (revision a07aba5d44204a7ca0d891a3da05af9960081e4c)
1*a07aba5dSTimm Baeder // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++14 -verify %s
2*a07aba5dSTimm Baeder // RUN: %clang_cc1 -std=c++14 -verify=ref %s
3*a07aba5dSTimm Baeder // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify=expected-cpp20 %s
4*a07aba5dSTimm Baeder // RUN: %clang_cc1 -std=c++20 -verify=ref %s
5*a07aba5dSTimm Baeder 
6*a07aba5dSTimm Baeder namespace WhileLoop {
7*a07aba5dSTimm Baeder   constexpr int f() {
8*a07aba5dSTimm Baeder     int i = 0;
9*a07aba5dSTimm Baeder     while(false) {
10*a07aba5dSTimm Baeder       i = i + 1;
11*a07aba5dSTimm Baeder     }
12*a07aba5dSTimm Baeder     return i;
13*a07aba5dSTimm Baeder   }
14*a07aba5dSTimm Baeder   static_assert(f() == 0, "");
15*a07aba5dSTimm Baeder 
16*a07aba5dSTimm Baeder 
17*a07aba5dSTimm Baeder   constexpr int f2() {
18*a07aba5dSTimm Baeder     int i = 0;
19*a07aba5dSTimm Baeder     while(i != 5) {
20*a07aba5dSTimm Baeder       i = i + 1;
21*a07aba5dSTimm Baeder     }
22*a07aba5dSTimm Baeder     return i;
23*a07aba5dSTimm Baeder   }
24*a07aba5dSTimm Baeder   static_assert(f2() == 5, "");
25*a07aba5dSTimm Baeder 
26*a07aba5dSTimm Baeder   constexpr int f3() {
27*a07aba5dSTimm Baeder     int i = 0;
28*a07aba5dSTimm Baeder     while(true) {
29*a07aba5dSTimm Baeder       i = i + 1;
30*a07aba5dSTimm Baeder 
31*a07aba5dSTimm Baeder       if (i == 5)
32*a07aba5dSTimm Baeder         break;
33*a07aba5dSTimm Baeder     }
34*a07aba5dSTimm Baeder     return i;
35*a07aba5dSTimm Baeder   }
36*a07aba5dSTimm Baeder   static_assert(f3() == 5, "");
37*a07aba5dSTimm Baeder 
38*a07aba5dSTimm Baeder   constexpr int f4() {
39*a07aba5dSTimm Baeder     int i = 0;
40*a07aba5dSTimm Baeder     while(i != 5) {
41*a07aba5dSTimm Baeder 
42*a07aba5dSTimm Baeder       i = i + 1;
43*a07aba5dSTimm Baeder       continue;
44*a07aba5dSTimm Baeder       i = i - 1;
45*a07aba5dSTimm Baeder     }
46*a07aba5dSTimm Baeder     return i;
47*a07aba5dSTimm Baeder   }
48*a07aba5dSTimm Baeder   static_assert(f4() == 5, "");
49*a07aba5dSTimm Baeder 
50*a07aba5dSTimm Baeder 
51*a07aba5dSTimm Baeder   constexpr int f5(bool b) {
52*a07aba5dSTimm Baeder     int i = 0;
53*a07aba5dSTimm Baeder 
54*a07aba5dSTimm Baeder     while(true) {
55*a07aba5dSTimm Baeder       if (!b) {
56*a07aba5dSTimm Baeder         if (i == 5)
57*a07aba5dSTimm Baeder           break;
58*a07aba5dSTimm Baeder       }
59*a07aba5dSTimm Baeder 
60*a07aba5dSTimm Baeder       if (b) {
61*a07aba5dSTimm Baeder         while (i != 10) {
62*a07aba5dSTimm Baeder           i = i + 1;
63*a07aba5dSTimm Baeder           if (i == 8)
64*a07aba5dSTimm Baeder             break;
65*a07aba5dSTimm Baeder 
66*a07aba5dSTimm Baeder           continue;
67*a07aba5dSTimm Baeder         }
68*a07aba5dSTimm Baeder       }
69*a07aba5dSTimm Baeder 
70*a07aba5dSTimm Baeder       if (b)
71*a07aba5dSTimm Baeder         break;
72*a07aba5dSTimm Baeder 
73*a07aba5dSTimm Baeder       i = i + 1;
74*a07aba5dSTimm Baeder       continue;
75*a07aba5dSTimm Baeder     }
76*a07aba5dSTimm Baeder 
77*a07aba5dSTimm Baeder     return i;
78*a07aba5dSTimm Baeder   }
79*a07aba5dSTimm Baeder   static_assert(f5(true) == 8, "");
80*a07aba5dSTimm Baeder   static_assert(f5(false) == 5, "");
81*a07aba5dSTimm Baeder 
82*a07aba5dSTimm Baeder #if 0
83*a07aba5dSTimm Baeder   /// FIXME: This is an infinite loop, which should
84*a07aba5dSTimm Baeder   ///   be rejected.
85*a07aba5dSTimm Baeder   constexpr int f6() {
86*a07aba5dSTimm Baeder     while(true);
87*a07aba5dSTimm Baeder   }
88*a07aba5dSTimm Baeder #endif
89*a07aba5dSTimm Baeder };
90*a07aba5dSTimm Baeder 
91*a07aba5dSTimm Baeder namespace DoWhileLoop {
92*a07aba5dSTimm Baeder 
93*a07aba5dSTimm Baeder   constexpr int f() {
94*a07aba5dSTimm Baeder     int i = 0;
95*a07aba5dSTimm Baeder     do {
96*a07aba5dSTimm Baeder       i = i + 1;
97*a07aba5dSTimm Baeder     } while(false);
98*a07aba5dSTimm Baeder     return i;
99*a07aba5dSTimm Baeder   }
100*a07aba5dSTimm Baeder   static_assert(f() == 1, "");
101*a07aba5dSTimm Baeder 
102*a07aba5dSTimm Baeder   constexpr int f2() {
103*a07aba5dSTimm Baeder     int i = 0;
104*a07aba5dSTimm Baeder     do {
105*a07aba5dSTimm Baeder       i = i + 1;
106*a07aba5dSTimm Baeder     } while(i != 5);
107*a07aba5dSTimm Baeder     return i;
108*a07aba5dSTimm Baeder   }
109*a07aba5dSTimm Baeder   static_assert(f2() == 5, "");
110*a07aba5dSTimm Baeder 
111*a07aba5dSTimm Baeder 
112*a07aba5dSTimm Baeder   constexpr int f3() {
113*a07aba5dSTimm Baeder     int i = 0;
114*a07aba5dSTimm Baeder     do {
115*a07aba5dSTimm Baeder       i = i + 1;
116*a07aba5dSTimm Baeder       if (i == 5)
117*a07aba5dSTimm Baeder         break;
118*a07aba5dSTimm Baeder     } while(true);
119*a07aba5dSTimm Baeder     return i;
120*a07aba5dSTimm Baeder   }
121*a07aba5dSTimm Baeder   static_assert(f3() == 5, "");
122*a07aba5dSTimm Baeder 
123*a07aba5dSTimm Baeder   constexpr int f4() {
124*a07aba5dSTimm Baeder     int i = 0;
125*a07aba5dSTimm Baeder     do {
126*a07aba5dSTimm Baeder       i = i + 1;
127*a07aba5dSTimm Baeder       continue;
128*a07aba5dSTimm Baeder       i = i - 1;
129*a07aba5dSTimm Baeder     } while(i != 5);
130*a07aba5dSTimm Baeder     return i;
131*a07aba5dSTimm Baeder   }
132*a07aba5dSTimm Baeder   static_assert(f4() == 5, "");
133*a07aba5dSTimm Baeder 
134*a07aba5dSTimm Baeder   constexpr int f5(bool b) {
135*a07aba5dSTimm Baeder     int i = 0;
136*a07aba5dSTimm Baeder 
137*a07aba5dSTimm Baeder     do {
138*a07aba5dSTimm Baeder       if (!b) {
139*a07aba5dSTimm Baeder         if (i == 5)
140*a07aba5dSTimm Baeder           break;
141*a07aba5dSTimm Baeder       }
142*a07aba5dSTimm Baeder 
143*a07aba5dSTimm Baeder       if (b) {
144*a07aba5dSTimm Baeder         do {
145*a07aba5dSTimm Baeder           i = i + 1;
146*a07aba5dSTimm Baeder           if (i == 8)
147*a07aba5dSTimm Baeder             break;
148*a07aba5dSTimm Baeder 
149*a07aba5dSTimm Baeder           continue;
150*a07aba5dSTimm Baeder         } while (i != 10);
151*a07aba5dSTimm Baeder       }
152*a07aba5dSTimm Baeder 
153*a07aba5dSTimm Baeder       if (b)
154*a07aba5dSTimm Baeder         break;
155*a07aba5dSTimm Baeder 
156*a07aba5dSTimm Baeder       i = i + 1;
157*a07aba5dSTimm Baeder       continue;
158*a07aba5dSTimm Baeder     } while(true);
159*a07aba5dSTimm Baeder 
160*a07aba5dSTimm Baeder     return i;
161*a07aba5dSTimm Baeder   }
162*a07aba5dSTimm Baeder   static_assert(f5(true) == 8, "");
163*a07aba5dSTimm Baeder   static_assert(f5(false) == 5, "");
164*a07aba5dSTimm Baeder 
165*a07aba5dSTimm Baeder #if __cplusplus >= 202002L
166*a07aba5dSTimm Baeder   constexpr int f6() {
167*a07aba5dSTimm Baeder     int i;
168*a07aba5dSTimm Baeder     do {
169*a07aba5dSTimm Baeder       i = 5;
170*a07aba5dSTimm Baeder       break;
171*a07aba5dSTimm Baeder     } while (true);
172*a07aba5dSTimm Baeder     return i;
173*a07aba5dSTimm Baeder   }
174*a07aba5dSTimm Baeder   static_assert(f6() == 5, "");
175*a07aba5dSTimm Baeder #endif
176*a07aba5dSTimm Baeder 
177*a07aba5dSTimm Baeder #if 0
178*a07aba5dSTimm Baeder   /// FIXME: This is an infinite loop, which should
179*a07aba5dSTimm Baeder   ///   be rejected.
180*a07aba5dSTimm Baeder   constexpr int f7() {
181*a07aba5dSTimm Baeder     while(true);
182*a07aba5dSTimm Baeder   }
183*a07aba5dSTimm Baeder #endif
184*a07aba5dSTimm Baeder };
185*a07aba5dSTimm Baeder 
186*a07aba5dSTimm Baeder namespace ForLoop {
187*a07aba5dSTimm Baeder   constexpr int f() {
188*a07aba5dSTimm Baeder     int i = 0;
189*a07aba5dSTimm Baeder     for (;false;) {
190*a07aba5dSTimm Baeder       i = i + 1;
191*a07aba5dSTimm Baeder     }
192*a07aba5dSTimm Baeder     return i;
193*a07aba5dSTimm Baeder   }
194*a07aba5dSTimm Baeder   static_assert(f() == 0, "");
195*a07aba5dSTimm Baeder 
196*a07aba5dSTimm Baeder   constexpr int f2() {
197*a07aba5dSTimm Baeder     int m = 0;
198*a07aba5dSTimm Baeder     for (int i = 0; i < 10; i = i + 1){
199*a07aba5dSTimm Baeder       m = i;
200*a07aba5dSTimm Baeder     }
201*a07aba5dSTimm Baeder     return m;
202*a07aba5dSTimm Baeder   }
203*a07aba5dSTimm Baeder   static_assert(f2() == 9, "");
204*a07aba5dSTimm Baeder 
205*a07aba5dSTimm Baeder   constexpr int f3() {
206*a07aba5dSTimm Baeder     int i = 0;
207*a07aba5dSTimm Baeder     for (; i != 5; i = i + 1);
208*a07aba5dSTimm Baeder     return i;
209*a07aba5dSTimm Baeder   }
210*a07aba5dSTimm Baeder   static_assert(f3() == 5, "");
211*a07aba5dSTimm Baeder 
212*a07aba5dSTimm Baeder   constexpr int f4() {
213*a07aba5dSTimm Baeder     int i = 0;
214*a07aba5dSTimm Baeder     for (;;) {
215*a07aba5dSTimm Baeder       i = i + 1;
216*a07aba5dSTimm Baeder 
217*a07aba5dSTimm Baeder       if (i == 5)
218*a07aba5dSTimm Baeder         break;
219*a07aba5dSTimm Baeder     }
220*a07aba5dSTimm Baeder     return i;
221*a07aba5dSTimm Baeder   }
222*a07aba5dSTimm Baeder   static_assert(f4() == 5, "");
223*a07aba5dSTimm Baeder 
224*a07aba5dSTimm Baeder   constexpr int f5() {
225*a07aba5dSTimm Baeder     int i = 0;
226*a07aba5dSTimm Baeder     for (;i != 5;) {
227*a07aba5dSTimm Baeder       i = i + 1;
228*a07aba5dSTimm Baeder       continue;
229*a07aba5dSTimm Baeder       i = i - 1;
230*a07aba5dSTimm Baeder     }
231*a07aba5dSTimm Baeder     return i;
232*a07aba5dSTimm Baeder   }
233*a07aba5dSTimm Baeder   static_assert(f5() == 5, "");
234*a07aba5dSTimm Baeder 
235*a07aba5dSTimm Baeder   constexpr int f6(bool b) {
236*a07aba5dSTimm Baeder     int i = 0;
237*a07aba5dSTimm Baeder 
238*a07aba5dSTimm Baeder     for (;true;) {
239*a07aba5dSTimm Baeder       if (!b) {
240*a07aba5dSTimm Baeder         if (i == 5)
241*a07aba5dSTimm Baeder           break;
242*a07aba5dSTimm Baeder       }
243*a07aba5dSTimm Baeder 
244*a07aba5dSTimm Baeder       if (b) {
245*a07aba5dSTimm Baeder         for (; i != 10; i = i + 1) {
246*a07aba5dSTimm Baeder           if (i == 8)
247*a07aba5dSTimm Baeder             break;
248*a07aba5dSTimm Baeder           continue;
249*a07aba5dSTimm Baeder         }
250*a07aba5dSTimm Baeder       }
251*a07aba5dSTimm Baeder 
252*a07aba5dSTimm Baeder       if (b)
253*a07aba5dSTimm Baeder         break;
254*a07aba5dSTimm Baeder 
255*a07aba5dSTimm Baeder       i = i + 1;
256*a07aba5dSTimm Baeder       continue;
257*a07aba5dSTimm Baeder     }
258*a07aba5dSTimm Baeder 
259*a07aba5dSTimm Baeder     return i;
260*a07aba5dSTimm Baeder   }
261*a07aba5dSTimm Baeder   static_assert(f6(true) == 8, "");
262*a07aba5dSTimm Baeder   static_assert(f6(false) == 5, "");
263*a07aba5dSTimm Baeder 
264*a07aba5dSTimm Baeder #if 0
265*a07aba5dSTimm Baeder   /// FIXME: This is an infinite loop, which should
266*a07aba5dSTimm Baeder   ///   be rejected.
267*a07aba5dSTimm Baeder   constexpr int f6() {
268*a07aba5dSTimm Baeder     for(;;);
269*a07aba5dSTimm Baeder   }
270*a07aba5dSTimm Baeder #endif
271*a07aba5dSTimm Baeder 
272*a07aba5dSTimm Baeder };
273*a07aba5dSTimm Baeder 
274*a07aba5dSTimm Baeder namespace RangeForLoop {
275*a07aba5dSTimm Baeder   constexpr int localArray() {
276*a07aba5dSTimm Baeder     int a[] = {1,2,3,4};
277*a07aba5dSTimm Baeder     int s = 0;
278*a07aba5dSTimm Baeder     for(int i : a) {
279*a07aba5dSTimm Baeder       s += i;
280*a07aba5dSTimm Baeder     }
281*a07aba5dSTimm Baeder     return s;
282*a07aba5dSTimm Baeder   }
283*a07aba5dSTimm Baeder   static_assert(localArray() == 10, "");
284*a07aba5dSTimm Baeder 
285*a07aba5dSTimm Baeder   constexpr int localArray2() {
286*a07aba5dSTimm Baeder     int a[] = {1,2,3,4};
287*a07aba5dSTimm Baeder     int s = 0;
288*a07aba5dSTimm Baeder     for(const int &i : a) {
289*a07aba5dSTimm Baeder       s += i;
290*a07aba5dSTimm Baeder     }
291*a07aba5dSTimm Baeder     return s;
292*a07aba5dSTimm Baeder   }
293*a07aba5dSTimm Baeder   static_assert(localArray2() == 10, "");
294*a07aba5dSTimm Baeder 
295*a07aba5dSTimm Baeder   constexpr int nested() {
296*a07aba5dSTimm Baeder     int s = 0;
297*a07aba5dSTimm Baeder     for (const int i : (int[]){1,2,3,4}) {
298*a07aba5dSTimm Baeder       int a[] = {i, i};
299*a07aba5dSTimm Baeder       for(int m : a) {
300*a07aba5dSTimm Baeder         s += m;
301*a07aba5dSTimm Baeder       }
302*a07aba5dSTimm Baeder     }
303*a07aba5dSTimm Baeder     return s;
304*a07aba5dSTimm Baeder   }
305*a07aba5dSTimm Baeder   static_assert(nested() == 20, "");
306*a07aba5dSTimm Baeder 
307*a07aba5dSTimm Baeder   constexpr int withBreak() {
308*a07aba5dSTimm Baeder     int s = 0;
309*a07aba5dSTimm Baeder     for (const int &i: (bool[]){false, true}) {
310*a07aba5dSTimm Baeder       if (i)
311*a07aba5dSTimm Baeder         break;
312*a07aba5dSTimm Baeder       s++;
313*a07aba5dSTimm Baeder     }
314*a07aba5dSTimm Baeder     return s;
315*a07aba5dSTimm Baeder   }
316*a07aba5dSTimm Baeder   static_assert(withBreak() == 1, "");
317*a07aba5dSTimm Baeder 
318*a07aba5dSTimm Baeder   constexpr void NoBody() {
319*a07aba5dSTimm Baeder     for (const int &i: (bool[]){false, true}); // expected-warning {{empty body}} \
320*a07aba5dSTimm Baeder                                                // expected-note {{semicolon on a separate line}} \
321*a07aba5dSTimm Baeder                                                // expected-cpp20-warning {{empty body}} \
322*a07aba5dSTimm Baeder                                                // expected-cpp20-note {{semicolon on a separate line}} \
323*a07aba5dSTimm Baeder                                                // ref-warning {{empty body}} \
324*a07aba5dSTimm Baeder                                                // ref-note {{semicolon on a separate line}}
325*a07aba5dSTimm Baeder   }
326*a07aba5dSTimm Baeder }
327*a07aba5dSTimm Baeder 
328*a07aba5dSTimm Baeder namespace Scopes {
329*a07aba5dSTimm Baeder   constexpr int foo() {
330*a07aba5dSTimm Baeder     int n = 0;
331*a07aba5dSTimm Baeder     {
332*a07aba5dSTimm Baeder       int m = 12;
333*a07aba5dSTimm Baeder     for (int i = 0;i < 10;++i) {
334*a07aba5dSTimm Baeder 
335*a07aba5dSTimm Baeder       {
336*a07aba5dSTimm Baeder         int a  = 10;
337*a07aba5dSTimm Baeder         {
338*a07aba5dSTimm Baeder           int b = 20;
339*a07aba5dSTimm Baeder           {
340*a07aba5dSTimm Baeder             int c = 30;
341*a07aba5dSTimm Baeder             continue;
342*a07aba5dSTimm Baeder           }
343*a07aba5dSTimm Baeder         }
344*a07aba5dSTimm Baeder       }
345*a07aba5dSTimm Baeder     }
346*a07aba5dSTimm Baeder     ++m;
347*a07aba5dSTimm Baeder     n = m;
348*a07aba5dSTimm Baeder     }
349*a07aba5dSTimm Baeder 
350*a07aba5dSTimm Baeder     ++n;
351*a07aba5dSTimm Baeder     return n;
352*a07aba5dSTimm Baeder   }
353*a07aba5dSTimm Baeder   static_assert(foo() == 14, "");
354*a07aba5dSTimm Baeder }
355