p4.cpp revision 30ecfad3af057bff74d1c98099eda0677525574e
1// RUN: %clang_cc1 -verify -std=c++11 -fcxx-exceptions %s 2 3namespace N { 4 typedef char C; 5} 6 7namespace M { 8 typedef double D; 9} 10 11struct NonLiteral { // expected-note 2{{no constexpr constructors}} 12 NonLiteral() {} 13 NonLiteral(int) {} 14}; 15struct Literal { 16 constexpr Literal() {} 17 explicit Literal(int); // expected-note 2 {{here}} 18 operator int() const { return 0; } 19}; 20 21// Note, the wording applies constraints to the definition of constexpr 22// constructors, but we intentionally apply all that we can to the declaration 23// instead. See DR1360. 24 25// In the definition of a constexpr constructor, each of the parameter types 26// shall be a literal type. 27struct S { 28 constexpr S(int, N::C); 29 constexpr S(int, NonLiteral, N::C); // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} 30 constexpr S(int, NonLiteral = 42); // expected-error {{constexpr constructor's 2nd parameter type 'NonLiteral' is not a literal type}} 31 32 // In addition, either its function-body shall be = delete or = default 33 constexpr S() = default; 34 constexpr S(Literal) = delete; 35}; 36 37// or it shall satisfy the following constraints: 38 39// - the class shall not have any virtual base classes; 40struct T : virtual S { // expected-note {{here}} 41 constexpr T(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}} 42}; 43namespace IndirectVBase { 44 struct A {}; 45 struct B : virtual A {}; // expected-note {{here}} 46 class C : public B { 47 public: 48 constexpr C(); // expected-error {{constexpr constructor not allowed in class with virtual base class}} 49 }; 50} 51 52// - its function-body shall not be a function-try-block; 53struct U { 54 constexpr U() 55 try // expected-error {{function try block not allowed in constexpr constructor}} 56 : u() { 57 } catch (...) { 58 throw; 59 } 60 int u; 61}; 62 63// - the compound-statememt of its function-body shall contain only 64struct V { 65 constexpr V() { 66 // - null statements, 67 ; 68 69 // - static_assert-declarations, 70 static_assert(true, "the impossible happened!"); 71 72 // - typedef declarations and alias-declarations that do not define classes 73 // or enumerations, 74 typedef int I; 75 typedef struct S T; 76 using J = int; 77 using K = int[sizeof(I) + sizeof(J)]; 78 // Note, the standard requires we reject this. 79 struct U; 80 81 // - using-declarations, 82 using N::C; 83 84 // - and using-directives; 85 using namespace N; 86 } 87 88 constexpr V(int(&)[1]) { 89 for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr constructor}} 90 /**/; 91 } 92 constexpr V(int(&)[2]) { 93 constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr constructor}} 94 } 95 constexpr V(int(&)[3]) { 96 constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr constructor}} 97 } 98 constexpr V(int(&)[4]) { 99 typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr constructor}} 100 } 101 constexpr V(int(&)[5]) { 102 using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr constructor}} 103 } 104 constexpr V(int(&)[6]) { 105 struct S3 { }; // expected-error {{types cannot be defined in a constexpr constructor}} 106 } 107 constexpr V(int(&)[7]) { 108 return; // expected-error {{statement not allowed in constexpr constructor}} 109 } 110}; 111 112// - every non-static data member and base class sub-object shall be initialized 113struct W { 114 int n; // expected-note {{member not initialized by constructor}} 115 constexpr W() {} // expected-error {{constexpr constructor must initialize all members}} 116}; 117struct AnonMembers { 118 int a; // expected-note {{member not initialized by constructor}} 119 union { // expected-note 2{{member not initialized by constructor}} 120 char b; 121 struct { 122 double c; 123 long d; // expected-note {{member not initialized by constructor}} 124 }; 125 union { 126 char e; 127 void *f; 128 }; 129 }; 130 struct { // expected-note {{member not initialized by constructor}} 131 long long g; 132 struct { 133 int h; // expected-note {{member not initialized by constructor}} 134 double i; // expected-note {{member not initialized by constructor}} 135 }; 136 union { // expected-note 2{{member not initialized by constructor}} 137 char *j; 138 AnonMembers *k; 139 }; 140 }; 141 142 constexpr AnonMembers(int(&)[1]) : a(), b(), g(), h(), i(), j() {} // ok 143 // missing d, i, j/k union 144 constexpr AnonMembers(int(&)[2]) : a(), c(), g(), h() {} // expected-error {{constexpr constructor must initialize all members}} 145 constexpr AnonMembers(int(&)[3]) : a(), e(), g(), h(), i(), k() {} // ok 146 // missing h, j/k union 147 constexpr AnonMembers(int(&)[4]) : a(), c(), d(), g(), i() {} // expected-error {{constexpr constructor must initialize all members}} 148 // missing b/c/d/e/f union 149 constexpr AnonMembers(int(&)[5]) : a(), g(), h(), i(), k() {} // expected-error {{constexpr constructor must initialize all members}} 150 // missing a, b/c/d/e/f union, g/h/i/j/k struct 151 constexpr AnonMembers(int(&)[6]) {} // expected-error {{constexpr constructor must initialize all members}} 152}; 153 154union Empty { 155 constexpr Empty() {} // ok 156} constexpr empty1; 157 158struct EmptyVariant { 159 union {}; 160 struct {}; 161 constexpr EmptyVariant() {} // ok 162} constexpr empty2; 163 164template<typename T> using Int = int; 165template<typename T> 166struct TemplateInit { 167 T a; 168 int b; // desired-note {{not initialized}} 169 Int<T> c; // desired-note {{not initialized}} 170 struct { 171 T d; 172 int e; // desired-note {{not initialized}} 173 Int<T> f; // desired-note {{not initialized}} 174 }; 175 struct { 176 Literal l; 177 Literal m; 178 Literal n[3]; 179 }; 180 union { // desired-note {{not initialized}} 181 T g; 182 T h; 183 }; 184 // FIXME: This is ill-formed (no diagnostic required). We should diagnose it. 185 constexpr TemplateInit() {} // desired-error {{must initialize all members}} 186}; 187template<typename T> struct TemplateInit2 { 188 Literal l; 189 constexpr TemplateInit2() {} // ok 190}; 191 192template<typename T> struct weak_ptr { 193 constexpr weak_ptr() : p(0) {} 194 T *p; 195}; 196template<typename T> struct enable_shared_from_this { 197 weak_ptr<T> weak_this; 198 constexpr enable_shared_from_this() {} // ok 199}; 200constexpr int f(enable_shared_from_this<int>); 201 202// - every constructor involved in initializing non-static data members and base 203// class sub-objects shall be a constexpr constructor. 204struct ConstexprBaseMemberCtors : Literal { 205 Literal l; 206 207 constexpr ConstexprBaseMemberCtors() : Literal(), l() {} // ok 208 constexpr ConstexprBaseMemberCtors(char) : // expected-error {{constexpr constructor never produces a constant expression}} 209 Literal(0), // expected-note {{non-constexpr constructor}} 210 l() {} 211 constexpr ConstexprBaseMemberCtors(double) : Literal(), // expected-error {{constexpr constructor never produces a constant expression}} 212 l(0) // expected-note {{non-constexpr constructor}} 213 {} 214}; 215 216// - every assignment-expression that is an initializer-caluse appearing 217// directly or indirectly within a brace-or-equal-initializer for a non-static 218// data member that is not named by a mem-initializer-id shall be a constant 219// expression; and 220// 221// Note, we deliberately do not implement this bullet, so that we can allow the 222// following example. (See N3308). 223struct X { 224 int a = 0; 225 int b = 2 * a + 1; // ok, not a constant expression. 226 227 constexpr X() {} 228 constexpr X(int c) : a(c) {} // ok, b initialized by 2 * c + 1 229}; 230 231// - every implicit conversion used in converting a constructor argument to the 232// corresponding parameter type and converting a full-expression to the 233// corresponding member type shall be one of those allowed in a constant 234// expression. 235// 236// We implement the proposed resolution of DR1364 and ignore this bullet. 237// However, we implement the intent of this wording as part of the p5 check that 238// the function must be able to produce a constant expression. 239int kGlobal; // expected-note {{here}} 240struct Z { 241 constexpr Z(int a) : n(a) {} 242 constexpr Z() : n(kGlobal) {} // expected-error {{constexpr constructor never produces a constant expression}} expected-note {{read of non-const}} 243 int n; 244}; 245 246 247namespace StdExample { 248 struct Length { 249 explicit constexpr Length(int i = 0) : val(i) { } 250 private: 251 int val; 252 }; 253} 254