1 // RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++14-extensions -Werror=c++20-extensions %s 2 // RUN: %clang_cc1 -verify -std=c++14 -fcxx-exceptions -DCXX14 -Werror=c++20-extensions %s 3 // RUN: %clang_cc1 -verify -std=c++20 -fcxx-exceptions -DCXX14 -DCXX2A %s 4 5 namespace N { 6 typedef char C; 7 } 8 9 namespace M { 10 typedef double D; 11 } 12 13 struct NonLiteral { // expected-note 2{{no constexpr constructors}} NonLiteralNonLiteral14 NonLiteral() {} NonLiteralNonLiteral15 NonLiteral(int) {} 16 }; 17 struct Literal { LiteralLiteral18 constexpr Literal() {} 19 explicit Literal(int); // expected-note 2 {{here}} operator intLiteral20 operator int() const { return 0; } 21 }; 22 23 // In the definition of a constexpr constructor, each of the parameter types 24 // shall be a literal type. 25 struct S { SS26 constexpr S(int, N::C) {} SS27 constexpr S(int, NonLiteral, N::C) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} SS28 constexpr S(int, NonLiteral = 42) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} 29 30 // In addition, either its function-body shall be = delete or = default 31 constexpr S() = default; 32 constexpr S(Literal) = delete; 33 }; 34 35 // or it shall satisfy the following constraints: 36 37 // - the class shall not have any virtual base classes; 38 struct T : virtual S { // expected-note {{here}} TT39 constexpr T() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} 40 }; 41 namespace IndirectVBase { 42 struct A {}; 43 struct B : virtual A {}; // expected-note {{here}} 44 class C : public B { 45 public: C()46 constexpr C() {} // expected-error {{constexpr constructor not allowed in class with virtual base class}} 47 }; 48 } 49 50 // - its function-body shall not be a function-try-block; 51 struct U { UU52 constexpr U() 53 try 54 #ifndef CXX2A 55 // expected-error@-2 {{function try block in constexpr constructor is a C++20 extension}} 56 #endif 57 : u() { 58 #ifndef CXX14 59 // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}} 60 #endif 61 } catch (...) { 62 throw; 63 } 64 int u; 65 }; 66 67 // - the compound-statememt of its function-body shall contain only 68 struct V { VV69 constexpr V() { 70 // - null statements, 71 ; 72 73 // - static_assert-declarations, 74 static_assert(true, "the impossible happened!"); 75 76 // - typedef declarations and alias-declarations that do not define classes 77 // or enumerations, 78 typedef int I; 79 typedef struct S T; 80 using J = int; 81 using K = int[sizeof(I) + sizeof(J)]; 82 // Note, the standard requires we reject this. 83 struct U; 84 85 // - using-declarations, 86 using N::C; 87 88 // - and using-directives; 89 using namespace N; 90 } 91 VV92 constexpr V(int(&)[1]) { 93 for (int n = 0; n < 10; ++n) 94 /**/; 95 #ifndef CXX14 96 // expected-error@-3 {{statement not allowed in constexpr constructor}} 97 #endif 98 } VV99 constexpr V(int(&)[2]) { 100 constexpr int a = 0; 101 #ifndef CXX14 102 // expected-error@-2 {{variable declaration in a constexpr constructor is a C++14 extension}} 103 #endif 104 } VV105 constexpr V(int(&)[3]) { 106 constexpr int ForwardDecl(int); 107 #ifndef CXX14 108 // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}} 109 #endif 110 } VV111 constexpr V(int(&)[4]) { 112 typedef struct { } S1; 113 #ifndef CXX14 114 // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}} 115 #endif 116 } VV117 constexpr V(int(&)[5]) { 118 using S2 = struct { }; 119 #ifndef CXX14 120 // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}} 121 #endif 122 } VV123 constexpr V(int(&)[6]) { 124 struct S3 { }; 125 #ifndef CXX14 126 // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}} 127 #endif 128 } VV129 constexpr V(int(&)[7]) { 130 return; 131 #ifndef CXX14 132 // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}} 133 #endif 134 } 135 }; 136 137 // - every non-static data member and base class sub-object shall be initialized 138 struct W { 139 int n; WW140 constexpr W() {} 141 #ifndef CXX2A 142 // expected-error@-2 {{constexpr constructor that does not initialize all members}} 143 // expected-note@-4 {{member not initialized by constructor}} 144 #endif 145 }; 146 struct AnonMembers { 147 int a; // expected-note 0-1{{member not initialized by constructor}} 148 union { // expected-note 0-2{{member not initialized by constructor}} 149 char b; 150 struct { 151 double c; 152 long d; // expected-note 0-1{{member not initialized by constructor}} 153 }; 154 union { 155 char e; 156 void *f; 157 }; 158 }; 159 struct { // expected-note 0-1{{member not initialized by constructor}} 160 long long g; 161 struct { 162 int h; // expected-note 0-1{{member not initialized by constructor}} 163 double i; // expected-note 0-1{{member not initialized by constructor}} 164 }; 165 union { // expected-note 0-2{{member not initialized by constructor}} 166 char *j; 167 AnonMembers *k; 168 }; 169 }; 170 AnonMembersAnonMembers171 constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok 172 // missing d, i, j/k union AnonMembersAnonMembers173 constexpr AnonMembers(int(&)[2]) : a(), c(), g(), h() {} 174 #ifndef CXX2A 175 // expected-error@-2 {{constexpr constructor that does not initialize all members}} 176 #endif AnonMembersAnonMembers177 constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok 178 // missing h, j/k union AnonMembersAnonMembers179 constexpr AnonMembers(int(&)[4]) : a(), c(), d(), g(), i() {} 180 #ifndef CXX2A 181 // expected-error@-2 {{constexpr constructor that does not initialize all members}} 182 #endif 183 // missing b/c/d/e/f union AnonMembersAnonMembers184 constexpr AnonMembers(int(&)[5]) : a(), g(), h(), i(), k() {} 185 #ifndef CXX2A 186 // expected-error@-2 {{constexpr constructor that does not initialize all members}} 187 #endif 188 // missing a, b/c/d/e/f union, g/h/i/j/k struct AnonMembersAnonMembers189 constexpr AnonMembers(int(&)[6]) {} 190 #ifndef CXX2A 191 // expected-error@-2 {{constexpr constructor that does not initialize all members}} 192 #endif 193 }; 194 195 union Empty { Empty()196 constexpr Empty() {} // ok 197 } constexpr empty1; 198 199 struct EmptyVariant { 200 union {}; // expected-warning {{does not declare anything}} 201 struct {}; // expected-warning {{does not declare anything}} EmptyVariantEmptyVariant202 constexpr EmptyVariant() {} // ok 203 } constexpr empty2; 204 205 template<typename T> using Int = int; 206 template<typename T> 207 struct TemplateInit { 208 T a; 209 int b; // desired-note {{not initialized}} 210 Int<T> c; // desired-note {{not initialized}} 211 struct { 212 T d; 213 int e; // desired-note {{not initialized}} 214 Int<T> f; // desired-note {{not initialized}} 215 }; 216 struct { 217 Literal l; 218 Literal m; 219 Literal n[3]; 220 }; 221 union { // desired-note {{not initialized}} 222 T g; 223 T h; 224 }; 225 // FIXME: This is ill-formed (no diagnostic required). We should diagnose it. TemplateInitTemplateInit226 constexpr TemplateInit() {} // desired-error {{must initialize all members}} 227 }; 228 template<typename T> struct TemplateInit2 { 229 Literal l; TemplateInit2TemplateInit2230 constexpr TemplateInit2() {} // ok 231 }; 232 233 template<typename T> struct weak_ptr { weak_ptrweak_ptr234 constexpr weak_ptr() : p(0) {} 235 T *p; 236 }; 237 template<typename T> struct enable_shared_from_this { 238 weak_ptr<T> weak_this; enable_shared_from_thisenable_shared_from_this239 constexpr enable_shared_from_this() {} // ok 240 }; 241 constexpr int f(enable_shared_from_this<int>); 242 243 // - every constructor involved in initializing non-static data members and base 244 // class sub-objects shall be a constexpr constructor. 245 // This will no longer be the case once we support P2448R2 246 struct ConstexprBaseMemberCtors : Literal { 247 Literal l; 248 ConstexprBaseMemberCtorsConstexprBaseMemberCtors249 constexpr ConstexprBaseMemberCtors() : Literal(), l() {} // ok ConstexprBaseMemberCtorsConstexprBaseMemberCtors250 constexpr ConstexprBaseMemberCtors(char) : // expected-error {{constexpr constructor never produces a constant expression}} 251 Literal(0), // expected-note {{non-constexpr constructor}} 252 l() {} ConstexprBaseMemberCtorsConstexprBaseMemberCtors253 constexpr ConstexprBaseMemberCtors(double) : Literal(), // expected-error {{constexpr constructor never produces a constant expression}} 254 l(0) // expected-note {{non-constexpr constructor}} 255 {} 256 }; 257 258 // - every assignment-expression that is an initializer-clause appearing 259 // directly or indirectly within a brace-or-equal-initializer for a non-static 260 // data member that is not named by a mem-initializer-id shall be a constant 261 // expression; and 262 // 263 // Note, we deliberately do not implement this bullet, so that we can allow the 264 // following example. (See N3308). 265 struct X { 266 int a = 0; 267 int b = 2 * a + 1; // ok, not a constant expression. 268 XX269 constexpr X() {} XX270 constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1 271 }; 272 273 union XU1 { int a; constexpr XU1() = default; }; 274 #ifndef CXX2A 275 // expected-error@-2{{cannot be marked constexpr}} 276 #endif 277 union XU2 { int a = 1; constexpr XU2() = default; }; 278 279 struct XU3 { 280 union { 281 int a; 282 }; 283 constexpr XU3() = default; 284 #ifndef CXX2A 285 // expected-error@-2{{cannot be marked constexpr}} 286 #endif 287 }; 288 struct XU4 { 289 union { 290 int a = 1; 291 }; 292 constexpr XU4() = default; 293 }; 294 295 static_assert(XU2().a == 1, ""); 296 static_assert(XU4().a == 1, ""); 297 298 // - every implicit conversion used in converting a constructor argument to the 299 // corresponding parameter type and converting a full-expression to the 300 // corresponding member type shall be one of those allowed in a constant 301 // expression. 302 // 303 // We implement the proposed resolution of DR1364 and ignore this bullet. 304 // However, we implement the intent of this wording as part of the p5 check that 305 // the function must be able to produce a constant expression. 306 int kGlobal; // expected-note {{here}} 307 struct Z { ZZ308 constexpr Z(int a) : n(a) {} ZZ309 constexpr Z() : n(kGlobal) {} // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}} 310 int n; 311 }; 312 313 314 namespace StdExample { 315 struct Length { LengthStdExample::Length316 explicit constexpr Length(int i = 0) : val(i) { } 317 private: 318 int val; 319 }; 320 } 321 322 namespace CtorLookup { 323 // Ensure that we look up which constructor will actually be used. 324 struct A { ACtorLookup::A325 constexpr A(const A&) {} ACtorLookup::A326 A(A&) {} 327 constexpr A(int = 0); 328 }; 329 330 struct B : A { 331 B() = default; 332 constexpr B(const B&); 333 constexpr B(B&); 334 }; 335 constexpr B::B(const B&) = default; 336 constexpr B::B(B&) = default; // expected-error {{cannot be marked constexpr}} 337 338 struct C { 339 A a; 340 C() = default; 341 constexpr C(const C&); 342 constexpr C(C&); 343 }; 344 constexpr C::C(const C&) = default; 345 constexpr C::C(C&) = default; // expected-error {{cannot be marked constexpr}} 346 } 347 348 namespace PR14503 { 349 template<typename> struct V { 350 union { 351 int n; 352 struct { 353 int x, 354 y; // expected-note {{subobject declared here}} 355 }; 356 }; VPR14503::V357 constexpr V() : x(0) {} 358 }; 359 360 // The constructor is still 'constexpr' here, but the result is not intended 361 // to be a constant expression. The standard is not clear on how this should 362 // work. 363 constexpr V<int> v; // expected-error {{constant expression}} expected-note {{subobject 'y' is not initialized}} 364 365 constexpr int k = V<int>().x; // FIXME: ok? 366 } 367