1 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -fcxx-exceptions -verify=ref,both %s 2 // RUN: %clang_cc1 -std=c++2a -fsyntax-only -fcxx-exceptions -verify=expected,both %s -fexperimental-new-constant-interpreter 3 4 template <unsigned N> 5 struct S { 6 S() requires (N==1) = default; 7 S() requires (N==2) {} // both-note {{declared here}} 8 consteval S() requires (N==3) = default; 9 }; 10 11 consteval int aConstevalFunction() { // both-error {{consteval function never produces a constant expression}} 12 S<2> s4; // both-note {{non-constexpr constructor 'S' cannot be used in a constant expression}} 13 return 0; 14 } 15 /// We're NOT calling the above function. The diagnostics should appear anyway. 16 17 namespace Covariant { 18 struct A { 19 virtual constexpr char f() const { return 'Z'; } 20 char a = f(); 21 }; 22 23 struct D : A {}; 24 struct Covariant1 { 25 D d; 26 virtual const A *f() const; 27 }; 28 29 struct Covariant3 : Covariant1 { 30 constexpr virtual const D *f() const { return &this->d; } 31 }; 32 33 constexpr Covariant3 cb; 34 constexpr const Covariant1 *cb1 = &cb; 35 static_assert(cb1->f()->a == 'Z'); 36 } 37 38 namespace DtorOrder { 39 struct Buf { 40 char buf[64]; 41 int n = 0; 42 constexpr void operator+=(char c) { buf[n++] = c; } 43 constexpr bool operator==(const char *str) const { 44 if (str[n] != 0) 45 return false; 46 47 for (int i = 0; i < n; ++i) { 48 if (buf[n] != str[n]) 49 return false; 50 } 51 return true; 52 53 return __builtin_memcmp(str, buf, n) == 0; 54 } 55 constexpr bool operator!=(const char *str) const { return !operator==(str); } 56 }; 57 58 struct A { 59 constexpr A(Buf &buf, char c) : buf(buf), c(c) { buf += c; } 60 constexpr ~A() { buf += (c - 32);} 61 constexpr operator bool() const { return true; } 62 Buf &buf; 63 char c; 64 }; 65 66 constexpr void abnormal_termination(Buf &buf) { 67 struct Indestructible { 68 constexpr ~Indestructible(); // not defined 69 }; 70 A a(buf, 'a'); 71 A(buf, 'b'); 72 int n = 0; 73 74 for (A &&c = A(buf, 'c'); A d = A(buf, 'd'); A(buf, 'e')) { 75 switch (A f(buf, 'f'); A g = A(buf, 'g')) { // both-warning {{boolean}} 76 case false: { 77 A x(buf, 'x'); 78 } 79 80 case true: { 81 A h(buf, 'h'); 82 switch (n++) { 83 case 0: 84 break; 85 case 1: 86 continue; 87 case 2: 88 return; 89 } 90 break; 91 } 92 93 default: 94 Indestructible indest; 95 } 96 97 A j = (A(buf, 'i'), A(buf, 'j')); 98 } 99 } 100 101 constexpr bool check_abnormal_termination() { 102 Buf buf = {}; 103 abnormal_termination(buf); 104 return buf == 105 "abBc" 106 "dfgh" /*break*/ "HGFijIJeED" 107 "dfgh" /*continue*/ "HGFeED" 108 "dfgh" /*return*/ "HGFD" 109 "CA"; 110 } 111 static_assert(check_abnormal_termination()); 112 } 113 114 namespace std { 115 struct type_info; 116 } 117 118 namespace TypeId { 119 struct A { 120 const std::type_info &ti = typeid(*this); 121 }; 122 struct A2 : A {}; 123 static_assert(&A().ti == &typeid(A)); 124 static_assert(&typeid((A2())) == &typeid(A2)); 125 extern A2 extern_a2; 126 static_assert(&typeid(extern_a2) == &typeid(A2)); 127 128 constexpr A2 a2; 129 constexpr const A &a1 = a2; 130 static_assert(&typeid(a1) == &typeid(A)); 131 132 struct B { 133 virtual void f(); 134 const std::type_info &ti1 = typeid(*this); 135 }; 136 struct B2 : B { 137 const std::type_info &ti2 = typeid(*this); 138 }; 139 static_assert(&B2().ti1 == &typeid(B)); 140 static_assert(&B2().ti2 == &typeid(B2)); 141 extern B2 extern_b2; 142 static_assert(&typeid(extern_b2) == &typeid(B2)); 143 144 constexpr B2 b2; 145 constexpr const B &b1 = b2; 146 static_assert(&typeid(b1) == &typeid(B2)); 147 148 constexpr bool side_effects() { 149 // Not polymorphic nor a glvalue. 150 bool OK = true; 151 (void)typeid(OK = false, A2()); // both-warning {{has no effect}} 152 if (!OK) return false; 153 154 // Not polymorphic. 155 A2 a2; 156 (void)typeid(OK = false, a2); // both-warning {{has no effect}} 157 if (!OK) return false; 158 159 // Not a glvalue. 160 (void)typeid(OK = false, B2()); // both-warning {{has no effect}} 161 if (!OK) return false; 162 163 // Polymorphic glvalue: operand evaluated. 164 OK = false; 165 B2 b2; 166 (void)typeid(OK = true, b2); // both-warning {{will be evaluated}} 167 return OK; 168 } 169 static_assert(side_effects()); 170 } 171 172 consteval int f(int i); 173 constexpr bool test(auto i) { 174 return f(0) == 0; 175 } 176 consteval int f(int i) { 177 return 2 * i; 178 } 179 static_assert(test(42)); 180