1 // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s 2 // RUN: %clang_cc1 -std=c++14 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s 3 // RUN: %clang_cc1 -std=c++20 -fexperimental-new-constant-interpreter -pedantic -verify=expected,both %s 4 // RUN: %clang_cc1 -pedantic -verify=ref,both %s 5 // RUN: %clang_cc1 -pedantic -std=c++14 -verify=ref,both %s 6 // RUN: %clang_cc1 -pedantic -std=c++20 -verify=ref,both %s 7 8 constexpr void doNothing() {} 9 constexpr int gimme5() { 10 doNothing(); 11 return 5; 12 } 13 static_assert(gimme5() == 5, ""); 14 15 16 template<typename T> constexpr T identity(T t) { 17 static_assert(true, ""); 18 return t; 19 } 20 static_assert(identity(true), ""); 21 static_assert(identity(true), ""); /// Compiled bytecode should be cached 22 static_assert(!identity(false), ""); 23 24 template<typename A, typename B> 25 constexpr bool sameSize() { 26 static_assert(sizeof(A) == sizeof(B), ""); // both-error {{static assertion failed}} \ 27 // both-note {{evaluates to}} 28 return true; 29 } 30 static_assert(sameSize<int, int>(), ""); 31 static_assert(sameSize<unsigned int, int>(), ""); 32 static_assert(sameSize<char, long>(), ""); // both-note {{in instantiation of function template specialization}} 33 34 35 constexpr auto add(int a, int b) -> int { 36 return identity(a) + identity(b); 37 } 38 39 constexpr int sub(int a, int b) { 40 return a - b; 41 } 42 static_assert(sub(5, 2) == 3, ""); 43 static_assert(sub(0, 5) == -5, ""); 44 45 constexpr int norm(int n) { 46 if (n >= 0) { 47 return identity(n); 48 } 49 return -identity(n); 50 } 51 static_assert(norm(5) == norm(-5), ""); 52 53 constexpr int square(int n) { 54 return norm(n) * norm(n); 55 } 56 static_assert(square(2) == 4, ""); 57 58 constexpr int add_second(int a, int b, bool doAdd = true) { 59 if (doAdd) 60 return a + b; 61 return a; 62 } 63 static_assert(add_second(10, 3, true) == 13, ""); 64 static_assert(add_second(10, 3) == 13, ""); 65 static_assert(add_second(300, -20, false) == 300, ""); 66 67 68 constexpr int sub(int a, int b, int c) { 69 return a - b - c; 70 } 71 static_assert(sub(10, 8, 2) == 0, ""); 72 73 74 constexpr int recursion(int i) { 75 doNothing(); 76 i = i - 1; 77 if (i == 0) 78 return identity(0); 79 80 return recursion(i); 81 } 82 static_assert(recursion(10) == 0, ""); 83 84 template<int N = 5> 85 constexpr decltype(N) getNum() { 86 return N; 87 } 88 static_assert(getNum<-2>() == -2, ""); 89 static_assert(getNum<10>() == 10, ""); 90 static_assert(getNum() == 5, ""); 91 92 constexpr int f(); // both-note {{declared here}} 93 static_assert(f() == 5, ""); // both-error {{not an integral constant expression}} \ 94 // both-note {{undefined function 'f'}} 95 constexpr int a() { 96 return f(); 97 } 98 constexpr int f() { 99 return 5; 100 } 101 static_assert(a() == 5, ""); 102 103 constexpr int invalid() { 104 // Invalid expression in visit(). 105 while(huh) {} // both-error {{use of undeclared identifier}} 106 return 0; 107 } 108 109 constexpr void invalid2() { 110 int i = 0; 111 // Invalid expression in discard(). 112 huh(); // both-error {{use of undeclared identifier}} 113 } 114 115 namespace FunctionPointers { 116 constexpr int add(int a, int b) { 117 return a + b; 118 } 119 120 struct S { int a; }; 121 constexpr S getS() { 122 return S{12}; 123 } 124 125 constexpr int applyBinOp(int a, int b, int (*op)(int, int)) { 126 return op(a, b); // both-note {{evaluates to a null function pointer}} 127 } 128 static_assert(applyBinOp(1, 2, add) == 3, ""); 129 static_assert(applyBinOp(1, 2, nullptr) == 3, ""); // both-error {{not an integral constant expression}} \ 130 // both-note {{in call to}} 131 132 133 constexpr int ignoreReturnValue() { 134 int (*foo)(int, int) = add; 135 136 foo(1, 2); 137 return 1; 138 } 139 static_assert(ignoreReturnValue() == 1, ""); 140 141 constexpr int createS(S (*gimme)()) { 142 gimme(); // Ignored return value 143 return gimme().a; 144 } 145 static_assert(createS(getS) == 12, ""); 146 147 namespace FunctionReturnType { 148 typedef int (*ptr)(int*); 149 typedef ptr (*pm)(); 150 151 constexpr int fun1(int* y) { 152 return *y + 10; 153 } 154 constexpr ptr fun() { 155 return &fun1; 156 } 157 static_assert(fun() == nullptr, ""); // both-error {{static assertion failed}} 158 159 constexpr int foo() { 160 int (*f)(int *) = fun(); 161 int m = 0; 162 163 m = f(&m); 164 165 return m; 166 } 167 static_assert(foo() == 10, ""); 168 169 struct S { 170 int i; 171 void (*fp)(); 172 }; 173 174 constexpr S s{ 12 }; 175 static_assert(s.fp == nullptr, ""); // zero-initialized function pointer. 176 177 constexpr int (*op)(int, int) = add; 178 constexpr bool b = op; 179 static_assert(op, ""); 180 static_assert(!!op, ""); 181 constexpr int (*op2)(int, int) = nullptr; 182 static_assert(!op2, ""); 183 184 int m() { return 5;} // both-note {{declared here}} 185 constexpr int (*invalidFnPtr)() = m; 186 static_assert(invalidFnPtr() == 5, ""); // both-error {{not an integral constant expression}} \ 187 // both-note {{non-constexpr function 'm'}} 188 189 190 namespace ToBool { 191 void mismatched(int x) {} 192 typedef void (*callback_t)(int); 193 void foo() { 194 callback_t callback = (callback_t)mismatched; // warns 195 /// Casts a function pointer to a boolean and then back to a function pointer. 196 /// This is extracted from test/Sema/callingconv-cast.c 197 callback = (callback_t)!mismatched; // both-warning {{address of function 'mismatched' will always evaluate to 'true'}} \ 198 // both-note {{prefix with the address-of operator to silence this warning}} 199 } 200 } 201 202 203 } 204 205 namespace Comparison { 206 void f(), g(); 207 constexpr void (*pf)() = &f, (*pg)() = &g; 208 209 constexpr bool u13 = pf < pg; // both-warning {{ordered comparison of function pointers}} \ 210 // both-error {{must be initialized by a constant expression}} \ 211 // both-note {{comparison between pointers to unrelated objects '&f' and '&g' has unspecified value}} 212 213 constexpr bool u14 = pf < (void(*)())nullptr; // both-warning {{ordered comparison of function pointers}} \ 214 // both-error {{must be initialized by a constant expression}} \ 215 // both-note {{comparison between pointers to unrelated objects '&f' and 'nullptr' has unspecified value}} 216 217 218 219 static_assert(pf != pg, ""); 220 static_assert(pf == &f, ""); 221 static_assert(pg == &g, ""); 222 } 223 224 constexpr int Double(int n) { return 2 * n; } 225 constexpr int Triple(int n) { return 3 * n; } 226 constexpr int Twice(int (*F)(int), int n) { return F(F(n)); } 227 constexpr int Quadruple(int n) { return Twice(Double, n); } 228 constexpr auto Select(int n) -> int (*)(int) { 229 return n == 2 ? &Double : n == 3 ? &Triple : n == 4 ? &Quadruple : 0; 230 } 231 constexpr int Apply(int (*F)(int), int n) { return F(n); } // both-note {{'F' evaluates to a null function pointer}} 232 233 constexpr int Invalid = Apply(Select(0), 0); // both-error {{must be initialized by a constant expression}} \ 234 // both-note {{in call to 'Apply(nullptr, 0)'}} 235 } 236 237 struct F { 238 constexpr bool ok() const { 239 return okRecurse(); 240 } 241 constexpr bool okRecurse() const { 242 return true; 243 } 244 }; 245 246 struct BodylessMemberFunction { 247 constexpr int first() const { 248 return second(); 249 } 250 constexpr int second() const { 251 return 1; 252 } 253 }; 254 255 constexpr int nyd(int m); 256 constexpr int doit() { return nyd(10); } 257 constexpr int nyd(int m) { return m; } 258 static_assert(doit() == 10, ""); 259 260 namespace InvalidCall { 261 struct S { 262 constexpr int a() const { // both-error {{never produces a constant expression}} 263 return 1 / 0; // both-note 2{{division by zero}} \ 264 // both-warning {{is undefined}} 265 } 266 }; 267 constexpr S s; 268 static_assert(s.a() == 1, ""); // both-error {{not an integral constant expression}} \ 269 // both-note {{in call to}} 270 271 /// This used to cause an assertion failure in the new constant interpreter. 272 constexpr void func(); // both-note {{declared here}} 273 struct SS { 274 constexpr SS() { func(); } // both-note {{undefined function }} 275 }; 276 constexpr SS ss; // both-error {{must be initialized by a constant expression}} \ 277 // both-note {{in call to 'SS()'}} 278 279 280 /// This should not emit a diagnostic. 281 constexpr int f(); 282 constexpr int a() { 283 return f(); 284 } 285 constexpr int f() { 286 return 5; 287 } 288 static_assert(a() == 5, ""); 289 290 } 291 292 namespace CallWithArgs { 293 /// This used to call problems during checkPotentialConstantExpression() runs. 294 constexpr void g(int a) {} 295 constexpr void f() { 296 g(0); 297 } 298 } 299 300 namespace ReturnLocalPtr { 301 constexpr int *p() { 302 int a = 12; 303 return &a; // both-warning {{address of stack memory}} 304 } 305 306 /// FIXME: Both interpreters should diagnose this. We're returning a pointer to a local 307 /// variable. 308 static_assert(p() == nullptr, ""); // both-error {{static assertion failed}} 309 310 constexpr const int &p2() { 311 int a = 12; // both-note {{declared here}} 312 return a; // both-warning {{reference to stack memory associated with local variable}} 313 } 314 315 static_assert(p2() == 12, ""); // both-error {{not an integral constant expression}} \ 316 // both-note {{read of variable whose lifetime has ended}} 317 } 318 319 namespace VoidReturn { 320 /// ReturnStmt with an expression in a void function used to cause problems. 321 constexpr void bar() {} 322 constexpr void foo() { 323 return bar(); 324 } 325 static_assert((foo(),1) == 1, ""); 326 } 327 328 namespace InvalidReclRefs { 329 void param(bool b) { // both-note {{declared here}} 330 static_assert(b, ""); // both-error {{not an integral constant expression}} \ 331 // both-note {{function parameter 'b' with unknown value}} 332 static_assert(true ? true : b, ""); 333 } 334 335 #if __cplusplus >= 202002L 336 consteval void param2(bool b) { // both-note {{declared here}} 337 static_assert(b, ""); // both-error {{not an integral constant expression}} \ 338 // both-note {{function parameter 'b' with unknown value}} 339 } 340 #endif 341 } 342 343 namespace TemplateUndefined { 344 template<typename T> constexpr int consume(T); 345 // ok, not a constant expression. 346 const int k = consume(0); 347 348 template<typename T> constexpr int consume(T) { return 0; } 349 // ok, constant expression. 350 constexpr int l = consume(0); 351 static_assert(l == 0, ""); 352 } 353 354 namespace PtrReturn { 355 constexpr void *a() { 356 return nullptr; 357 } 358 static_assert(a() == nullptr, ""); 359 } 360 361 namespace Variadic { 362 struct S { int a; bool b; }; 363 364 constexpr void variadic_function(int a, ...) {} 365 constexpr int f1() { 366 variadic_function(1, S{'a', false}); 367 return 1; 368 } 369 static_assert(f1() == 1, ""); 370 371 constexpr int variadic_function2(...) { 372 return 12; 373 } 374 static_assert(variadic_function2() == 12, ""); 375 static_assert(variadic_function2(1, 2, 3, 4, 5) == 12, ""); 376 static_assert(variadic_function2(1, variadic_function2()) == 12, ""); 377 378 constexpr int (*VFP)(...) = variadic_function2; 379 static_assert(VFP() == 12, ""); 380 381 /// Member functions 382 struct Foo { 383 int a = 0; 384 constexpr void bla(...) {} 385 constexpr S bla2(...) { 386 return S{12, true}; 387 } 388 constexpr Foo(...) : a(1337) {} 389 constexpr Foo(void *c, bool b, void*p, ...) : a('a' + b) {} 390 constexpr Foo(int a, const S* s, ...) : a(a) {} 391 }; 392 393 constexpr int foo2() { 394 Foo f(1, nullptr); 395 auto s = f.bla2(1, 2, S{1, false}); 396 return s.a + s.b; 397 } 398 static_assert(foo2() == 13, ""); 399 400 constexpr Foo _f = 123; 401 static_assert(_f.a == 1337, ""); 402 403 constexpr Foo __f(nullptr, false, nullptr, nullptr, 'a', Foo()); 404 static_assert(__f.a == 'a', ""); 405 406 407 #if __cplusplus >= 202002L 408 namespace VariadicVirtual { 409 class A { 410 public: 411 constexpr virtual void foo(int &a, ...) { 412 a = 1; 413 } 414 }; 415 416 class B : public A { 417 public: 418 constexpr void foo(int &a, ...) override { 419 a = 2; 420 } 421 }; 422 423 constexpr int foo() { 424 B b; 425 int a; 426 b.foo(a, 1,2,nullptr); 427 return a; 428 } 429 static_assert(foo() == 2, ""); 430 } // VariadicVirtual 431 432 namespace VariadicQualified { 433 class A { 434 public: 435 constexpr virtual int foo(...) const { 436 return 5; 437 } 438 }; 439 class B : public A {}; 440 class C : public B { 441 public: 442 constexpr int foo(...) const override { 443 return B::foo(1,2,3); // B doesn't have a foo(), so this should call A::foo(). 444 } 445 constexpr int foo2() const { 446 return this->A::foo(1,2,3,this); 447 } 448 }; 449 constexpr C c; 450 static_assert(c.foo() == 5); 451 static_assert(c.foo2() == 5); 452 } // VariadicQualified 453 #endif 454 455 } 456 457 namespace Packs { 458 template<typename...T> 459 constexpr int foo() { return sizeof...(T); } 460 static_assert(foo<int, char>() == 2, ""); 461 static_assert(foo<>() == 0, ""); 462 } 463 464 namespace AddressOf { 465 struct S {} s; 466 static_assert(__builtin_addressof(s) == &s, ""); 467 468 struct T { constexpr T *operator&() const { return nullptr; } int n; } t; 469 constexpr T *pt = __builtin_addressof(t); 470 static_assert(&pt->n == &t.n, ""); 471 472 struct U { int n : 5; } u; 473 int *pbf = __builtin_addressof(u.n); // both-error {{address of bit-field requested}} 474 475 S *ptmp = __builtin_addressof(S{}); // both-error {{taking the address of a temporary}} \ 476 // both-warning {{temporary whose address is used as value of local variable 'ptmp' will be destroyed at the end of the full-expression}} 477 478 constexpr int foo() {return 1;} 479 static_assert(__builtin_addressof(foo) == foo, ""); 480 481 constexpr _Complex float F = {3, 4}; // both-warning {{'_Complex' is a C99 extension}} 482 static_assert(__builtin_addressof(F) == &F, ""); 483 484 void testAddressof(int x) { 485 static_assert(&x == __builtin_addressof(x), ""); 486 } 487 } 488 489 namespace std { 490 template <typename T> struct remove_reference { using type = T; }; 491 template <typename T> struct remove_reference<T &> { using type = T; }; 492 template <typename T> struct remove_reference<T &&> { using type = T; }; 493 template <typename T> 494 constexpr typename std::remove_reference<T>::type&& move(T &&t) noexcept { 495 return static_cast<typename std::remove_reference<T>::type &&>(t); 496 } 497 } 498 /// The std::move declaration above gets translated to a builtin function. 499 namespace Move { 500 #if __cplusplus >= 202002L 501 consteval int f_eval() { // both-note 12{{declared here}} 502 return 0; 503 } 504 505 /// From test/SemaCXX/cxx2a-consteval. 506 struct Copy { 507 int(*ptr)(); 508 constexpr Copy(int(*p)() = nullptr) : ptr(p) {} 509 consteval Copy(const Copy&) = default; 510 }; 511 512 constexpr const Copy &to_lvalue_ref(const Copy &&a) { 513 return a; 514 } 515 516 void test() { 517 constexpr const Copy C; 518 // there is no the copy constructor call when its argument is a prvalue because of garanteed copy elision. 519 // so we need to test with both prvalue and xvalues. 520 { Copy c(C); } 521 { Copy c((Copy(&f_eval))); } // both-error {{cannot take address of consteval}} 522 { Copy c(std::move(C)); } 523 { Copy c(std::move(Copy(&f_eval))); } // both-error {{is not a constant expression}} \ 524 // both-note {{to a consteval}} 525 { Copy c(to_lvalue_ref((Copy(&f_eval)))); } // both-error {{is not a constant expression}} \ 526 // both-note {{to a consteval}} 527 { Copy c(to_lvalue_ref(std::move(C))); } 528 { Copy c(to_lvalue_ref(std::move(Copy(&f_eval)))); } // both-error {{is not a constant expression}} \ 529 // both-note {{to a consteval}} 530 { Copy c = Copy(C); } 531 { Copy c = Copy(Copy(&f_eval)); } // both-error {{cannot take address of consteval}} 532 { Copy c = Copy(std::move(C)); } 533 { Copy c = Copy(std::move(Copy(&f_eval))); } // both-error {{is not a constant expression}} \ 534 // both-note {{to a consteval}} 535 { Copy c = Copy(to_lvalue_ref(Copy(&f_eval))); } // both-error {{is not a constant expression}} \ 536 // both-note {{to a consteval}} 537 { Copy c = Copy(to_lvalue_ref(std::move(C))); } 538 { Copy c = Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); } // both-error {{is not a constant expression}} \ 539 // both-note {{to a consteval}} 540 { Copy c; c = Copy(C); } 541 { Copy c; c = Copy(Copy(&f_eval)); } // both-error {{cannot take address of consteval}} 542 { Copy c; c = Copy(std::move(C)); } 543 { Copy c; c = Copy(std::move(Copy(&f_eval))); } // both-error {{is not a constant expression}} \ 544 // both-note {{to a consteval}} 545 { Copy c; c = Copy(to_lvalue_ref(Copy(&f_eval))); } // both-error {{is not a constant expression}} \ 546 // both-note {{to a consteval}} 547 { Copy c; c = Copy(to_lvalue_ref(std::move(C))); } 548 { Copy c; c = Copy(to_lvalue_ref(std::move(Copy(&f_eval)))); } // both-error {{is not a constant expression}} \ 549 // both-note {{to a consteval}} 550 } 551 #endif 552 constexpr int A = std::move(5); 553 static_assert(A == 5, ""); 554 } 555 556 namespace StaticLocals { 557 void test() { 558 static int j; // both-note {{declared here}} 559 static_assert(&j != nullptr, ""); // both-warning {{always true}} 560 561 static_assert(j == 0, ""); // both-error {{not an integral constant expression}} \ 562 // both-note {{read of non-const variable 'j'}} 563 564 static int k = 0; // both-note {{declared here}} 565 static_assert(k == 0, ""); // both-error {{not an integral constant expression}} \ 566 // both-note {{read of non-const variable 'k'}} 567 568 static const int l = 12; 569 static_assert(l == 12, ""); 570 571 static const int m; // both-error {{default initialization}} 572 static_assert(m == 0, ""); 573 } 574 } 575 576 namespace Local { 577 /// We used to run into infinite recursin here because we were 578 /// trying to evaluate t's initializer while evaluating t's initializer. 579 int a() { 580 const int t=t; 581 return t; 582 } 583 } 584 585 namespace VariadicOperator { 586 struct Callable { 587 float& operator()(...); 588 }; 589 590 void test_callable(Callable c) { 591 float &fr = c(10); 592 } 593 } 594 595 namespace WeakCompare { 596 [[gnu::weak]]void weak_method(); 597 static_assert(weak_method != nullptr, ""); // both-error {{not an integral constant expression}} \ 598 // both-note {{comparison against address of weak declaration '&weak_method' can only be performed at runtim}} 599 600 constexpr auto A = &weak_method; 601 static_assert(A != nullptr, ""); // both-error {{not an integral constant expression}} \ 602 // both-note {{comparison against address of weak declaration '&weak_method' can only be performed at runtim}} 603 } 604 605 namespace FromIntegral { 606 #if __cplusplus >= 202002L 607 typedef double (*DoubleFn)(); 608 int a[(int)DoubleFn((void*)-1)()]; // both-error {{not allowed at file scope}} \ 609 // both-warning {{variable length arrays}} 610 int b[(int)DoubleFn((void*)(-1 + 1))()]; // both-error {{not allowed at file scope}} \ 611 // expected-note {{evaluates to a null function pointer}} \ 612 // both-warning {{variable length arrays}} 613 #endif 614 } 615 616 namespace { 617 template <typename T> using id = T; 618 template <typename T> 619 constexpr void g() { 620 constexpr id<void (T)> f; 621 } 622 623 static_assert((g<int>(), true), ""); 624 } 625 626 namespace { 627 /// The InitListExpr here is of void type. 628 void bir [[clang::annotate("B", {1, 2, 3, 4})]] (); // both-error {{'annotate' attribute requires parameter 1 to be a constant expression}} \ 629 // both-note {{subexpression not valid in a constant expression}} 630 } 631 632 namespace FuncPtrParam { 633 void foo(int(&a)()) { 634 *a; // both-warning {{expression result unused}} 635 } 636 } 637 638 namespace { 639 void f() noexcept; 640 void (&r)() = f; 641 void (&cond3)() = r; 642 } 643 644 namespace FunctionCast { 645 // When folding, we allow functions to be cast to different types. Such 646 // cast functions cannot be called, even if they're constexpr. 647 constexpr int f() { return 1; } 648 typedef double (*DoubleFn)(); 649 typedef int (*IntFn)(); 650 int a[(int)DoubleFn(f)()]; // both-error {{variable length array}} \ 651 // both-warning {{are a Clang extension}} 652 int b[(int)IntFn(f)()]; // ok 653 } 654 655 #if __cplusplus >= 202002L 656 namespace StableAddress { 657 template<unsigned N> struct str { 658 char arr[N]; 659 }; 660 // FIXME: Deduction guide not needed with P1816R0. 661 template<unsigned N> str(const char (&)[N]) -> str<N>; 662 663 template<str s> constexpr int sum() { 664 int n = 0; 665 for (char c : s.arr) 666 n += c; 667 return n; 668 } 669 static_assert(sum<str{"$hello $world."}>() == 1234, ""); 670 } 671 #endif 672