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 { 31 constexpr T(); 32 constexpr int f() const; 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++14}} 66#else 67 // expected-error@-5 {{defaulted definition of copy assignment operator is not constexpr}} 68#endif 69}; 70#ifdef CXX1Y 71struct T2 { 72 int n = 0; 73 constexpr T2 &operator=(const T2&) = default; // ok 74}; 75struct T3 { 76 constexpr T3 &operator=(const T3&) const = default; 77 // expected-error@-1 {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}} 78}; 79#endif 80struct U { 81 constexpr U SelfReturn() const; 82 constexpr int SelfParam(U) const; 83}; 84 85struct V : virtual U { // expected-note {{here}} 86 constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}} 87}; 88 89// or a compound-statememt that contains only [CXX11] 90constexpr int AllowedStmtsCXX11() { 91 // - null statements 92 ; 93 94 // - static_assert-declarations 95 static_assert(true, "the impossible happened!"); 96 97 // - typedef declarations and alias-declarations that do not define classes 98 // or enumerations 99 typedef int I; 100 typedef struct S T; 101 using J = int; 102 using K = int[sizeof(I) + sizeof(J)]; 103 // Note, the standard requires we reject this. 104 struct U; 105 106 // - using-declarations 107 using N::C; 108 109 // - using-directives 110 using namespace N; 111 112 // - and exactly one return statement 113 return sizeof(K) + sizeof(C) + sizeof(K); 114} 115 116// or a compound-statement that does not contain [CXX1Y] 117constexpr int DisallowedStmtsCXX1Y_1() { 118 // - an asm-definition 119 asm("int3"); // expected-error {{statement not allowed in constexpr function}} 120 return 0; 121} 122constexpr int DisallowedStmtsCXX1Y_2() { 123 // - a goto statement 124 goto x; // expected-error {{statement not allowed in constexpr function}} 125x: 126 return 0; 127} 128constexpr int DisallowedStmtsCXX1Y_3() { 129 // - a try-block, 130 try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}} 131 return 0; 132} 133constexpr int DisallowedStmtsCXX1Y_4() { 134 // - a definition of a variable of non-literal type 135 NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}} 136 return 0; 137} 138constexpr int DisallowedStmtsCXX1Y_5() { 139 // - a definition of a variable of static storage duration 140 static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}} 141 return n; 142} 143constexpr int DisallowedStmtsCXX1Y_6() { 144 // - a definition of a variable of thread storage duration 145 thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}} 146 return n; 147} 148constexpr int DisallowedStmtsCXX1Y_7() { 149 // - a definition of a variable for which no initialization is performed 150 int n; // expected-error {{variables defined in a constexpr function must be initialized}} 151 return 0; 152} 153 154constexpr int ForStmt() { 155 for (int n = 0; n < 10; ++n) 156#ifndef CXX1Y 157 // expected-error@-2 {{statement not allowed in constexpr function}} 158#endif 159 return 0; 160} 161constexpr int VarDecl() { 162 int a = 0; 163#ifndef CXX1Y 164 // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} 165#endif 166 return 0; 167} 168constexpr int ConstexprVarDecl() { 169 constexpr int a = 0; 170#ifndef CXX1Y 171 // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} 172#endif 173 return 0; 174} 175constexpr int VarWithCtorDecl() { 176 Literal a; 177#ifndef CXX1Y 178 // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} 179#endif 180 return 0; 181} 182NonLiteral nl; 183constexpr NonLiteral &ExternNonLiteralVarDecl() { 184 extern NonLiteral nl; 185#ifndef CXX1Y 186 // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}} 187#endif 188 return nl; 189} 190static_assert(&ExternNonLiteralVarDecl() == &nl, ""); 191constexpr int FuncDecl() { 192 constexpr int ForwardDecl(int); 193#ifndef CXX1Y 194 // expected-error@-2 {{use of this statement in a constexpr function is a C++14 extension}} 195#endif 196 return ForwardDecl(42); 197} 198constexpr int ClassDecl1() { 199 typedef struct { } S1; 200#ifndef CXX1Y 201 // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}} 202#endif 203 return 0; 204} 205constexpr int ClassDecl2() { 206 using S2 = struct { }; 207#ifndef CXX1Y 208 // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}} 209#endif 210 return 0; 211} 212constexpr int ClassDecl3() { 213 struct S3 { }; 214#ifndef CXX1Y 215 // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}} 216#endif 217 return 0; 218} 219constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}} 220constexpr int MultiReturn() { 221 return 0; 222 return 0; 223#ifndef CXX1Y 224 // expected-error@-2 {{multiple return statements in constexpr function}} 225 // expected-note@-4 {{return statement}} 226#endif 227} 228 229// - every constructor call and implicit conversion used in initializing the 230// return value shall be one of those allowed in a constant expression. 231// 232// We implement the proposed resolution of DR1364 and ignore this bullet. 233// However, we implement the spirit of the check as part of the p5 checking that 234// a constexpr function must be able to produce a constant expression. 235namespace DR1364 { 236 constexpr int f(int k) { 237 return k; // ok, even though lvalue-to-rvalue conversion of a function 238 // parameter is not allowed in a constant expression. 239 } 240 int kGlobal; // expected-note {{here}} 241 constexpr int f() { // expected-error {{constexpr function never produces a constant expression}} 242 return kGlobal; // expected-note {{read of non-const}} 243 } 244} 245 246namespace rdar13584715 { 247 typedef __PTRDIFF_TYPE__ ptrdiff_t; 248 249 template<typename T> struct X { 250 static T value() {}; 251 }; 252 253 void foo(ptrdiff_t id) { 254 switch (id) { 255 case reinterpret_cast<ptrdiff_t>(&X<long>::value): // expected-error{{case value is not a constant expression}} \ 256 // expected-note{{reinterpret_cast is not allowed in a constant expression}} 257 break; 258 } 259 } 260} 261 262namespace std_example { 263 constexpr int square(int x) { 264 return x * x; 265 } 266 constexpr long long_max() { 267 return 2147483647; 268 } 269 constexpr int abs(int x) { 270 if (x < 0) 271#ifndef CXX1Y 272 // expected-error@-2 {{C++14}} 273#endif 274 x = -x; 275 return x; 276 } 277 constexpr int first(int n) { 278 static int value = n; // expected-error {{static variable not permitted}} 279 return value; 280 } 281 constexpr int uninit() { 282 int a; // expected-error {{must be initialized}} 283 return a; 284 } 285 constexpr int prev(int x) { 286 return --x; 287 } 288#ifndef CXX1Y 289 // expected-error@-4 {{never produces a constant expression}} 290 // expected-note@-4 {{subexpression}} 291#endif 292 constexpr int g(int x, int n) { 293 int r = 1; 294 while (--n > 0) r *= x; 295 return r; 296 } 297#ifndef CXX1Y 298 // expected-error@-5 {{C++14}} 299 // expected-error@-5 {{statement not allowed}} 300#endif 301} 302