brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.6 KiB · 51990ee Raw
295 lines · cpp
1// RUN: %clang_cc1 -fcxx-exceptions -verify=expected,beforecxx14,beforecxx20,beforecxx23 -std=c++11 %s2// RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,beforecxx20,beforecxx23,cxx14_20 -std=c++14 %s3// RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,aftercxx20,beforecxx23,cxx14_20 -std=c++20  %s4// RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,aftercxx20 -std=c++23 %s5 6namespace N {7  typedef char C;8}9 10namespace M {11  typedef double D;12}13 14struct NonLiteral { // beforecxx23-note 2{{no constexpr constructors}}15  NonLiteral() {}16  NonLiteral(int) {}17};18struct Literal {19  constexpr Literal() {}20  operator int() const { return 0; }21};22 23struct S {24  virtual int ImplicitlyVirtual() const = 0; // beforecxx20-note {{overridden virtual function}}25};26struct SS : S {27  int ImplicitlyVirtual() const;28};29 30// The definition of a constexpr function shall satisfy the following31// constraints:32struct T : SS, NonLiteral {33  constexpr T();34  constexpr int f() const;35 36  //  - it shall not be virtual; [until C++20]37  virtual constexpr int ExplicitlyVirtual() const { return 0; } // beforecxx20-error {{virtual function cannot be constexpr}}38 39  constexpr int ImplicitlyVirtual() const { return 0; } // beforecxx20-error {{virtual function cannot be constexpr}}40 41  virtual constexpr int OutOfLineVirtual() const; // beforecxx20-error {{virtual function cannot be constexpr}}42 43  //  - its return type shall be a literal type;44  // Once we support P2448R2 constexpr functions will be allowd to return non-literal types45  // The destructor will also be allowed46  constexpr NonLiteral NonLiteralReturn() const { return {}; } // beforecxx23-error {{constexpr function's return type 'NonLiteral' is not a literal type}}47  constexpr void VoidReturn() const { return; }                // beforecxx14-error {{constexpr function's return type 'void' is not a literal type}}48  constexpr ~T();                                              // beforecxx20-error {{destructor cannot be declared constexpr}}49 50  typedef NonLiteral F() const;51  constexpr F NonLiteralReturn2; // ok until definition52 53  //  - each of its parameter types shall be a literal type;54  // Once we support P2448R2 constexpr functions will be allowd to have parameters of non-literal types55  constexpr int NonLiteralParam(NonLiteral) const { return 0; } // beforecxx23-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}56  typedef int G(NonLiteral) const;57  constexpr G NonLiteralParam2; // ok until definition58 59  //  - its function-body shall be = delete, = default,60  constexpr int Deleted() const = delete;61  // It's not possible for the function-body to legally be "= default" here62  // (that is, for a non-constructor function) in C++11.63  // Other than constructors, only the copy- and move-assignment operators and64  // destructor can be defaulted. Destructors can't be constexpr since they65  // don't have a literal return type. Defaulted assignment operators can't be66  // constexpr since they can't be const.67  constexpr T &operator=(const T &) = default; // beforecxx14-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} \68                                               // beforecxx14-warning {{C++14}} \69                                               // cxx14_20-error{{defaulted definition of copy assignment operator cannot be marked constexpr}}70};71 72constexpr int T::OutOfLineVirtual() const { return 0; }73#if __cplusplus >= 201402L74struct T2 {75  int n = 0;76  constexpr T2 &operator=(const T2&) = default; // ok77};78struct T3 {79  constexpr T3 &operator=(const T3 &) const = default; // beforecxx20-error {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}} \80                                                       // aftercxx20-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} \81                                                       // aftercxx20-note {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}82};83#endif84struct U {85  constexpr U SelfReturn() const;86  constexpr int SelfParam(U) const;87};88 89struct 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]94constexpr int AllowedStmtsCXX11() {95  //  - null statements96  ;97 98  //  - static_assert-declarations99  static_assert(true, "the impossible happened!");100 101  //  - typedef declarations and alias-declarations that do not define classes102  //    or enumerations103  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-declarations111  using N::C;112 113  //  - using-directives114  using namespace N;115 116  //  - and exactly one return statement117  return sizeof(K) + sizeof(C) + sizeof(K);118}119 120//  or a compound-statement that does not contain [C++14]121constexpr int DisallowedStmtsCXX14_1(bool b) {122  //  - an asm-definition123  if (b)124    asm("int3"); // beforecxx20-warning {{use of this statement in a constexpr function is a C++20 extension}}125  return 0;126}127constexpr int DisallowedStmtsCXX14_2() {128  return 0; // beforecxx14-note {{previous}}129  //  - a goto statement130  goto x; // beforecxx23-warning {{use of this statement in a constexpr function is a C++23 extension}}131  x:;132    return 0; // beforecxx14-warning {{multiple return}}133}134constexpr int DisallowedStmtsCXX14_2_1() {135merp: // beforecxx23-warning {{use of this statement in a constexpr function is a C++23 extension}}136  return 0;137}138constexpr int DisallowedStmtsCXX14_3() {139  //  - a try-block,140  try {  }  // beforecxx20-warning {{use of this statement in a constexpr function is a C++20 extension}}141  catch (...) {}142  return 0;143}144constexpr int DisallowedStmtsCXX14_4() {145  //  - a definition of a variable of non-literal type146  return 0;147  NonLiteral nl; // beforecxx23-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++23}} \148                 // beforecxx23-note@14  {{'NonLiteral' is not literal}}149}150 151constexpr int DisallowedStmtsCXX14_5() {152  return 0;153  //  - a definition of a variable of static storage duration154  static constexpr int n = 123; // beforecxx23-warning {{definition of a static variable in a constexpr function is a C++23 extension}} \155                               //  beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}156}157 158constexpr int DisallowedStmtsCXX14_6() {159  //  - a definition of a variable of thread storage duration160  return 0;161  thread_local constexpr int n = 123; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} \162                                      // beforecxx23-warning {{definition of a thread_local variable in a constexpr function is a C++23 extension}}163}164constexpr int DisallowedStmtsCXX14_7() {165  //  - a definition of a variable for which no initialization is performed166  return 0;167  int n; // beforecxx20-warning {{uninitialized variable in a constexpr function}}168}169 170constexpr int ForStmt() {171  for (int n = 0; n < 10; ++n) {} // beforecxx14-error {{statement not allowed in constexpr function}}172    return 0;173}174 175constexpr int VarDecl() {176  int a = 0; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}177  return 0;178}179constexpr int ConstexprVarDecl() {180  constexpr int a = 0; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}181  return 0;182}183constexpr int VarWithCtorDecl() {184  Literal a; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}185  return 0;186}187 188NonLiteral nl;189constexpr NonLiteral &ExternNonLiteralVarDecl() {190  extern NonLiteral nl; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}191  return nl;192}193static_assert(&ExternNonLiteralVarDecl() == &nl, "");194 195constexpr int FuncDecl() {196  constexpr int ForwardDecl(int); // beforecxx14-warning {{use of this statement in a constexpr function is a C++14 extension}}197  return ForwardDecl(42);198}199 200constexpr int ClassDecl1() {201  typedef struct {} S1; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}}202  return 0;203}204 205constexpr int ClassDecl2() {206  using S2 = struct {}; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}}207  return 0;208}209 210constexpr int ClassDecl3() {211  struct S3 {}; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}}212  return 0;213}214 215constexpr int NoReturn() {} // beforecxx23-error {{no return statement in constexpr function}}216constexpr int MultiReturn() {217  return 0; // beforecxx14-note {{return statement}}218  return 0; // beforecxx14-warning {{multiple return statements in constexpr function}}219}220 221//  - every constructor call and implicit conversion used in initializing the222//    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 that226// 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 function230              // parameter is not allowed in a constant expression.231  }232  int kGlobal; // beforecxx23-note {{here}}233  constexpr int f() { // beforecxx23-error {{constexpr function never produces a constant expression}}234    return kGlobal;   // beforecxx23-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) // beforecxx14-warning {{C++14}}263      x = -x;264    return x;265  }266  constexpr int first(int n) {267    return 0;268    static int value = n; // beforecxx23-warning {{definition of a static variable in a constexpr function is a C++23 extension}} \269                          // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}270  }271  constexpr int uninit() {272    int a; // beforecxx20-warning {{uninitialized}}273    return a;274  }275  constexpr int prev(int x) { // beforecxx14-error {{never produces a constant expression}}276    return --x;               // beforecxx14-note {{subexpression}}277  }278 279  constexpr int g(int x, int n) {280    int r = 1; // beforecxx14-warning{{C++14}}281    while (--n > 0) // beforecxx14-error {{statement not allowed in constexpr function}}282      r *= x;283    return r;284  }285}286 287struct Base {288 constexpr Base() = default;289};290struct Derived : virtual Base { // expected-note 3{{virtual base class declared here}}291  constexpr Derived() = default; // expected-error {{default constructor cannot be 'constexpr' in a class with virtual base class}}292  constexpr Derived(const Derived&) = default; // expected-error {{copy constructor cannot be 'constexpr' in a class with virtual base class}}293  constexpr Derived(Derived&&) = default; // expected-error {{move constructor cannot be 'constexpr' in a class with virtual base class}}294};295