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