| 1 | // RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions -Werror=c++1y-extensions -Werror=c++2a-extensions %s |
| 2 | // RUN: %clang_cc1 -verify -std=c++1y -fcxx-exceptions -DCXX1Y -Werror=c++2a-extensions %s |
| 3 | // RUN: %clang_cc1 -verify -std=c++2a -fcxx-exceptions -DCXX1Y -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}} |
| 14 | NonLiteral() {} |
| 15 | NonLiteral(int) {} |
| 16 | }; |
| 17 | struct Literal { |
| 18 | constexpr Literal() {} |
| 19 | explicit Literal(int); // expected-note 2 {{here}} |
| 20 | 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 { |
| 26 | constexpr S(int, N::C) {} |
| 27 | constexpr S(int, NonLiteral, N::C) {} // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} |
| 28 | 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}} |
| 39 | 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: |
| 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 { |
| 52 | constexpr U() |
| 53 | try |
| 54 | #ifndef CXX2A |
| 55 | // expected-error@-2 {{function try block in constexpr constructor is a C++2a extension}} |
| 56 | #endif |
| 57 | : u() { |
| 58 | #ifndef CXX1Y |
| 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 { |
| 69 | 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 | |
| 92 | constexpr V(int(&)[1]) { |
| 93 | for (int n = 0; n < 10; ++n) |
| 94 | /**/; |
| 95 | #ifndef CXX1Y |
| 96 | // expected-error@-3 {{statement not allowed in constexpr constructor}} |
| 97 | #endif |
| 98 | } |
| 99 | constexpr V(int(&)[2]) { |
| 100 | constexpr int a = 0; |
| 101 | #ifndef CXX1Y |
| 102 | // expected-error@-2 {{variable declaration in a constexpr constructor is a C++14 extension}} |
| 103 | #endif |
| 104 | } |
| 105 | constexpr V(int(&)[3]) { |
| 106 | constexpr int ForwardDecl(int); |
| 107 | #ifndef CXX1Y |
| 108 | // expected-error@-2 {{use of this statement in a constexpr constructor is a C++14 extension}} |
| 109 | #endif |
| 110 | } |
| 111 | constexpr V(int(&)[4]) { |
| 112 | typedef struct { } S1; |
| 113 | #ifndef CXX1Y |
| 114 | // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}} |
| 115 | #endif |
| 116 | } |
| 117 | constexpr V(int(&)[5]) { |
| 118 | using S2 = struct { }; |
| 119 | #ifndef CXX1Y |
| 120 | // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}} |
| 121 | #endif |
| 122 | } |
| 123 | constexpr V(int(&)[6]) { |
| 124 | struct S3 { }; |
| 125 | #ifndef CXX1Y |
| 126 | // expected-error@-2 {{type definition in a constexpr constructor is a C++14 extension}} |
| 127 | #endif |
| 128 | } |
| 129 | constexpr V(int(&)[7]) { |
| 130 | return; |
| 131 | #ifndef CXX1Y |
| 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; // expected-note {{member not initialized by constructor}} |
| 140 | constexpr W() {} // expected-error {{constexpr constructor must initialize all members}} |
| 141 | }; |
| 142 | struct AnonMembers { |
| 143 | int a; // expected-note {{member not initialized by constructor}} |
| 144 | union { // expected-note 2{{member not initialized by constructor}} |
| 145 | char b; |
| 146 | struct { |
| 147 | double c; |
| 148 | long d; // expected-note {{member not initialized by constructor}} |
| 149 | }; |
| 150 | union { |
| 151 | char e; |
| 152 | void *f; |
| 153 | }; |
| 154 | }; |
| 155 | struct { // expected-note {{member not initialized by constructor}} |
| 156 | long long g; |
| 157 | struct { |
| 158 | int h; // expected-note {{member not initialized by constructor}} |
| 159 | double i; // expected-note {{member not initialized by constructor}} |
| 160 | }; |
| 161 | union { // expected-note 2{{member not initialized by constructor}} |
| 162 | char *j; |
| 163 | AnonMembers *k; |
| 164 | }; |
| 165 | }; |
| 166 | |
| 167 | constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok |
| 168 | // missing d, i, j/k union |
| 169 | constexpr AnonMembers(int(&)[2]) : a(), c(), g(), h() {} // expected-error {{constexpr constructor must initialize all members}} |
| 170 | constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok |
| 171 | // missing h, j/k union |
| 172 | constexpr AnonMembers(int(&)[4]) : a(), c(), d(), g(), i() {} // expected-error {{constexpr constructor must initialize all members}} |
| 173 | // missing b/c/d/e/f union |
| 174 | constexpr AnonMembers(int(&)[5]) : a(), g(), h(), i(), k() {} // expected-error {{constexpr constructor must initialize all members}} |
| 175 | // missing a, b/c/d/e/f union, g/h/i/j/k struct |
| 176 | constexpr AnonMembers(int(&)[6]) {} // expected-error {{constexpr constructor must initialize all members}} |
| 177 | }; |
| 178 | |
| 179 | union Empty { |
| 180 | constexpr Empty() {} // ok |
| 181 | } constexpr empty1; |
| 182 | |
| 183 | struct EmptyVariant { |
| 184 | union {}; |
| 185 | struct {}; |
| 186 | constexpr EmptyVariant() {} // ok |
| 187 | } constexpr empty2; |
| 188 | |
| 189 | template<typename T> using Int = int; |
| 190 | template<typename T> |
| 191 | struct TemplateInit { |
| 192 | T a; |
| 193 | int b; // desired-note {{not initialized}} |
| 194 | Int<T> c; // desired-note {{not initialized}} |
| 195 | struct { |
| 196 | T d; |
| 197 | int e; // desired-note {{not initialized}} |
| 198 | Int<T> f; // desired-note {{not initialized}} |
| 199 | }; |
| 200 | struct { |
| 201 | Literal l; |
| 202 | Literal m; |
| 203 | Literal n[3]; |
| 204 | }; |
| 205 | union { // desired-note {{not initialized}} |
| 206 | T g; |
| 207 | T h; |
| 208 | }; |
| 209 | // FIXME: This is ill-formed (no diagnostic required). We should diagnose it. |
| 210 | constexpr TemplateInit() {} // desired-error {{must initialize all members}} |
| 211 | }; |
| 212 | template<typename T> struct TemplateInit2 { |
| 213 | Literal l; |
| 214 | constexpr TemplateInit2() {} // ok |
| 215 | }; |
| 216 | |
| 217 | template<typename T> struct weak_ptr { |
| 218 | constexpr weak_ptr() : p(0) {} |
| 219 | T *p; |
| 220 | }; |
| 221 | template<typename T> struct enable_shared_from_this { |
| 222 | weak_ptr<T> weak_this; |
| 223 | constexpr enable_shared_from_this() {} // ok |
| 224 | }; |
| 225 | constexpr int f(enable_shared_from_this<int>); |
| 226 | |
| 227 | // - every constructor involved in initializing non-static data members and base |
| 228 | // class sub-objects shall be a constexpr constructor. |
| 229 | struct ConstexprBaseMemberCtors : Literal { |
| 230 | Literal l; |
| 231 | |
| 232 | constexpr ConstexprBaseMemberCtors() : Literal(), l() {} // ok |
| 233 | constexpr ConstexprBaseMemberCtors(char) : // expected-error {{constexpr constructor never produces a constant expression}} |
| 234 | Literal(0), // expected-note {{non-constexpr constructor}} |
| 235 | l() {} |
| 236 | constexpr ConstexprBaseMemberCtors(double) : Literal(), // expected-error {{constexpr constructor never produces a constant expression}} |
| 237 | l(0) // expected-note {{non-constexpr constructor}} |
| 238 | {} |
| 239 | }; |
| 240 | |
| 241 | // - every assignment-expression that is an initializer-clause appearing |
| 242 | // directly or indirectly within a brace-or-equal-initializer for a non-static |
| 243 | // data member that is not named by a mem-initializer-id shall be a constant |
| 244 | // expression; and |
| 245 | // |
| 246 | // Note, we deliberately do not implement this bullet, so that we can allow the |
| 247 | // following example. (See N3308). |
| 248 | struct X { |
| 249 | int a = 0; |
| 250 | int b = 2 * a + 1; // ok, not a constant expression. |
| 251 | |
| 252 | constexpr X() {} |
| 253 | constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1 |
| 254 | }; |
| 255 | |
| 256 | union XU1 { int a; constexpr XU1() = default; }; // expected-error{{not constexpr}} |
| 257 | union XU2 { int a = 1; constexpr XU2() = default; }; |
| 258 | |
| 259 | struct XU3 { |
| 260 | union { |
| 261 | int a; |
| 262 | }; |
| 263 | constexpr XU3() = default; // expected-error{{not constexpr}} |
| 264 | }; |
| 265 | struct XU4 { |
| 266 | union { |
| 267 | int a = 1; |
| 268 | }; |
| 269 | constexpr XU4() = default; |
| 270 | }; |
| 271 | |
| 272 | static_assert(XU2().a == 1, ""); |
| 273 | static_assert(XU4().a == 1, ""); |
| 274 | |
| 275 | // - every implicit conversion used in converting a constructor argument to the |
| 276 | // corresponding parameter type and converting a full-expression to the |
| 277 | // corresponding member type shall be one of those allowed in a constant |
| 278 | // expression. |
| 279 | // |
| 280 | // We implement the proposed resolution of DR1364 and ignore this bullet. |
| 281 | // However, we implement the intent of this wording as part of the p5 check that |
| 282 | // the function must be able to produce a constant expression. |
| 283 | int kGlobal; // expected-note {{here}} |
| 284 | struct Z { |
| 285 | constexpr Z(int a) : n(a) {} |
| 286 | constexpr Z() : n(kGlobal) {} // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}} |
| 287 | int n; |
| 288 | }; |
| 289 | |
| 290 | |
| 291 | namespace StdExample { |
| 292 | struct Length { |
| 293 | explicit constexpr Length(int i = 0) : val(i) { } |
| 294 | private: |
| 295 | int val; |
| 296 | }; |
| 297 | } |
| 298 | |
| 299 | namespace CtorLookup { |
| 300 | // Ensure that we look up which constructor will actually be used. |
| 301 | struct A { |
| 302 | constexpr A(const A&) {} |
| 303 | A(A&) {} |
| 304 | constexpr A(int = 0); |
| 305 | }; |
| 306 | |
| 307 | struct B : A { |
| 308 | B() = default; |
| 309 | constexpr B(const B&); |
| 310 | constexpr B(B&); |
| 311 | }; |
| 312 | constexpr B::B(const B&) = default; |
| 313 | constexpr B::B(B&) = default; // expected-error {{not constexpr}} |
| 314 | |
| 315 | struct C { |
| 316 | A a; |
| 317 | C() = default; |
| 318 | constexpr C(const C&); |
| 319 | constexpr C(C&); |
| 320 | }; |
| 321 | constexpr C::C(const C&) = default; |
| 322 | constexpr C::C(C&) = default; // expected-error {{not constexpr}} |
| 323 | } |
| 324 | |
| 325 | namespace PR14503 { |
| 326 | template<typename> struct V { |
| 327 | union { |
| 328 | int n; |
| 329 | struct { |
| 330 | int x, |
| 331 | y; |
| 332 | }; |
| 333 | }; |
| 334 | constexpr V() : x(0) {} |
| 335 | }; |
| 336 | |
| 337 | // The constructor is still 'constexpr' here, but the result is not intended |
| 338 | // to be a constant expression. The standard is not clear on how this should |
| 339 | // work. |
| 340 | constexpr V<int> v; // expected-error {{constant expression}} expected-note {{subobject of type 'int' is not initialized}} |
| 341 | |
| 342 | constexpr int k = V<int>().x; // FIXME: ok? |
| 343 | } |
| 344 | |