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