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