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