p3.cpp revision 5528ac9f40ec6cb54e7096908bf2beeed511bce4
1// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions %s 2// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y %s 3 4namespace N { 5 typedef char C; 6} 7 8namespace M { 9 typedef double D; 10} 11 12struct NonLiteral { // expected-note 3{{no constexpr constructors}} 13 NonLiteral() {} 14 NonLiteral(int) {} 15}; 16struct Literal { 17 constexpr Literal() {} 18 operator int() const { return 0; } 19}; 20 21struct S { 22 virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}} 23}; 24struct SS : S { 25 int ImplicitlyVirtual() const; 26}; 27 28// The definition of a constexpr function shall satisfy the following 29// constraints: 30struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}} 31 constexpr T(); 32 constexpr int f() const; // expected-error {{non-literal type 'T' cannot have constexpr members}} 33 34 // - it shall not be virtual; 35 virtual constexpr int ExplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}} 36 37 constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}} 38 39 // - its return type shall be a literal type; 40 constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}} 41 constexpr void VoidReturn() const { return; } 42#ifndef CXX1Y 43 // expected-error@-2 {{constexpr function's return type 'void' is not a literal type}} 44#endif 45 constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}} 46 typedef NonLiteral F() const; 47 constexpr F NonLiteralReturn2; // ok until definition 48 49 // - each of its parameter types shall be a literal type; 50 constexpr int NonLiteralParam(NonLiteral) const { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} 51 typedef int G(NonLiteral) const; 52 constexpr G NonLiteralParam2; // ok until definition 53 54 // - its function-body shall be = delete, = default, 55 constexpr int Deleted() const = delete; 56 // It's not possible for the function-body to legally be "= default" here 57 // (that is, for a non-constructor function) in C++11. 58 // Other than constructors, only the copy- and move-assignment operators and 59 // destructor can be defaulted. Destructors can't be constexpr since they 60 // don't have a literal return type. Defaulted assignment operators can't be 61 // constexpr since they can't be const. 62 constexpr T &operator=(const T&) = default; 63#ifndef CXX1Y 64 // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} 65 // expected-warning@-3 {{C++1y}} 66#endif 67}; 68struct U { 69 constexpr U SelfReturn() const; 70 constexpr int SelfParam(U) const; 71}; 72 73struct V : virtual U { // expected-note {{here}} 74 constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}} 75}; 76 77// or a compound-statememt that contains only [CXX11] 78constexpr int AllowedStmtsCXX11() { 79 // - null statements 80 ; 81 82 // - static_assert-declarations 83 static_assert(true, "the impossible happened!"); 84 85 // - typedef declarations and alias-declarations that do not define classes 86 // or enumerations 87 typedef int I; 88 typedef struct S T; 89 using J = int; 90 using K = int[sizeof(I) + sizeof(J)]; 91 // Note, the standard requires we reject this. 92 struct U; 93 94 // - using-declarations 95 using N::C; 96 97 // - using-directives 98 using namespace N; 99 100 // - and exactly one return statement 101 return sizeof(K) + sizeof(C) + sizeof(K); 102} 103 104// or a compound-statement that does not contain [CXX1Y] 105constexpr int DisallowedStmtsCXX1Y_1() { 106 // - an asm-definition 107 asm("int3"); // expected-error {{statement not allowed in constexpr function}} 108 return 0; 109} 110constexpr int DisallowedStmtsCXX1Y_2() { 111 // - a goto statement 112 goto x; // expected-error {{statement not allowed in constexpr function}} 113x: 114 return 0; 115} 116constexpr int DisallowedStmtsCXX1Y_3() { 117 // - a try-block, 118 try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}} 119 return 0; 120} 121constexpr int DisallowedStmtsCXX1Y_4() { 122 // - a definition of a variable of non-literal type 123 NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}} 124 return 0; 125} 126constexpr int DisallowedStmtsCXX1Y_5() { 127 // - a definition of a variable of static storage duration 128 static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}} 129 return n; 130} 131constexpr int DisallowedStmtsCXX1Y_6() { 132 // - a definition of a variable of thread storage duration 133 thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}} 134 return n; 135} 136constexpr int DisallowedStmtsCXX1Y_7() { 137 // - a definition of a variable for which no initialization is performed 138 int n; // expected-error {{variables defined in a constexpr function must be initialized}} 139 return 0; 140} 141 142constexpr int ForStmt() { 143 for (int n = 0; n < 10; ++n) 144#ifndef CXX1Y 145 // expected-error@-2 {{statement not allowed in constexpr function}} 146#else 147 // FIXME: Once we support evaluating a for-statement, this diagnostic should disappear. 148 // expected-error@-6 {{never produces a constant expression}} 149 // expected-note@-6 {{subexpression}} 150#endif 151 return 0; 152} 153constexpr int VarDecl() { 154 int a = 0; 155#ifndef CXX1Y 156 // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} 157#endif 158 return 0; 159} 160constexpr int ConstexprVarDecl() { 161 constexpr int a = 0; 162#ifndef CXX1Y 163 // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} 164#endif 165 return 0; 166} 167constexpr int VarWithCtorDecl() { 168 Literal a; 169#ifndef CXX1Y 170 // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} 171#endif 172 return 0; 173} 174NonLiteral nl; 175constexpr NonLiteral &ExternNonLiteralVarDecl() { 176 extern NonLiteral nl; 177#ifndef CXX1Y 178 // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}} 179#endif 180 return nl; 181} 182static_assert(&ExternNonLiteralVarDecl() == &nl, ""); 183constexpr int FuncDecl() { 184 constexpr int ForwardDecl(int); 185#ifndef CXX1Y 186 // expected-error@-2 {{use of this statement in a constexpr function is a C++1y extension}} 187#endif 188 return ForwardDecl(42); 189} 190constexpr int ClassDecl1() { 191 typedef struct { } S1; 192#ifndef CXX1Y 193 // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}} 194#endif 195 return 0; 196} 197constexpr int ClassDecl2() { 198 using S2 = struct { }; 199#ifndef CXX1Y 200 // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}} 201#endif 202 return 0; 203} 204constexpr int ClassDecl3() { 205 struct S3 { }; 206#ifndef CXX1Y 207 // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}} 208#endif 209 return 0; 210} 211constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}} 212constexpr int MultiReturn() { 213 return 0; 214 return 0; 215#ifndef CXX1Y 216 // expected-error@-2 {{multiple return statements in constexpr function}} 217 // expected-note@-4 {{return statement}} 218#endif 219} 220 221// - every constructor call and implicit conversion used in initializing the 222// return value shall be one of those allowed in a constant expression. 223// 224// We implement the proposed resolution of DR1364 and ignore this bullet. 225// However, we implement the spirit of the check as part of the p5 checking that 226// a constexpr function must be able to produce a constant expression. 227namespace DR1364 { 228 constexpr int f(int k) { 229 return k; // ok, even though lvalue-to-rvalue conversion of a function 230 // parameter is not allowed in a constant expression. 231 } 232 int kGlobal; // expected-note {{here}} 233 constexpr int f() { // expected-error {{constexpr function never produces a constant expression}} 234 return kGlobal; // expected-note {{read of non-const}} 235 } 236} 237 238namespace rdar13584715 { 239 typedef __PTRDIFF_TYPE__ ptrdiff_t; 240 241 template<typename T> struct X { 242 static T value() {}; 243 }; 244 245 void foo(ptrdiff_t id) { 246 switch (id) { 247 case reinterpret_cast<ptrdiff_t>(&X<long>::value): // expected-error{{case value is not a constant expression}} \ 248 // expected-note{{reinterpret_cast is not allowed in a constant expression}} 249 break; 250 } 251 } 252} 253 254namespace std_example { 255 constexpr int square(int x) { 256 return x * x; 257 } 258 constexpr long long_max() { 259 return 2147483647; 260 } 261 constexpr int abs(int x) { 262 if (x < 0) 263#ifndef CXX1Y 264 // expected-error@-2 {{C++1y}} 265#endif 266 x = -x; 267 return x; 268 } 269 constexpr int first(int n) { 270 static int value = n; // expected-error {{static variable not permitted}} 271 return value; 272 } 273 constexpr int uninit() { 274 int a; // expected-error {{must be initialized}} 275 return a; 276 } 277 constexpr int prev(int x) { 278 return --x; 279 } 280#ifndef CXX1Y 281 // expected-error@-4 {{never produces a constant expression}} 282 // expected-note@-4 {{subexpression}} 283#endif 284 constexpr int g(int x, int n) { 285 int r = 1; 286 while (--n > 0) r *= x; 287 return r; 288 } 289#ifndef CXX1Y 290 // expected-error@-5 {{C++1y}} 291 // expected-error@-5 {{statement not allowed}} 292#else 293 // FIXME: This should be allowed. 294 // expected-error@-10 {{never produces a constant}} 295 // expected-note@-9 {{subexpression}} 296#endif 297} 298