Home | History | Annotate | Download | only in dcl.constexpr
      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