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