Home | History | Annotate | Download | only in dcl.constexpr
      1 // RUN: %clang_cc1 -verify -std=c++11 %s
      2 
      3 namespace N {
      4   typedef char C;
      5 }
      6 
      7 namespace M {
      8   typedef double D;
      9 }
     10 
     11 struct NonLiteral { // expected-note 2{{no constexpr constructors}}
     12   NonLiteral() {}
     13   NonLiteral(int) {}
     14 };
     15 struct Literal {
     16   constexpr Literal() {}
     17   operator int() const { return 0; }
     18 };
     19 
     20 struct S {
     21   virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}}
     22 };
     23 struct SS : S {
     24   int ImplicitlyVirtual() const;
     25 };
     26 
     27 // The definition of a constexpr function shall satisfy the following
     28 // constraints:
     29 struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}}
     30   constexpr T();
     31   constexpr int f(); // expected-error {{non-literal type 'T' cannot have constexpr members}}
     32 
     33   //  - it shall not be virtual;
     34   virtual constexpr int ExplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
     35 
     36   constexpr int ImplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
     37 
     38   //  - its return type shall be a literal type;
     39   constexpr NonLiteral NonLiteralReturn() { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
     40   constexpr void VoidReturn() { return; } // expected-error {{constexpr function's return type 'void' is not a literal type}}
     41   constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}}
     42   typedef NonLiteral F();
     43   constexpr F NonLiteralReturn2; // ok until definition
     44 
     45   //  - each of its parameter types shall be a literal type;
     46   constexpr int NonLiteralParam(NonLiteral) { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
     47   typedef int G(NonLiteral);
     48   constexpr G NonLiteralParam2; // ok until definition
     49 
     50   //  - its function-body shall be = delete, = default,
     51   constexpr int Deleted() = delete;
     52   // It's not possible for the function-body to legally be "= default" here.
     53   // Other than constructors, only the copy- and move-assignment operators and
     54   // destructor can be defaulted. Destructors can't be constexpr since they
     55   // don't have a literal return type. Defaulted assignment operators can't be
     56   // constexpr since they can't be const.
     57   constexpr T &operator=(const T&) = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
     58 };
     59 struct U {
     60   constexpr U SelfReturn();
     61   constexpr int SelfParam(U);
     62 };
     63 
     64 struct V : virtual U { // expected-note {{here}}
     65   constexpr int F() { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
     66 };
     67 
     68 //  or a compound-statememt that contains only
     69 constexpr int AllowedStmts() {
     70   //  - null statements
     71   ;
     72 
     73   //  - static_assert-declarations
     74   static_assert(true, "the impossible happened!");
     75 
     76   //  - typedef declarations and alias-declarations that do not define classes
     77   //    or enumerations
     78   typedef int I;
     79   typedef struct S T;
     80   using J = int;
     81   using K = int[sizeof(I) + sizeof(J)];
     82   // Note, the standard requires we reject this.
     83   struct U;
     84 
     85   //  - using-declarations
     86   using N::C;
     87 
     88   //  - using-directives
     89   using namespace N;
     90 
     91   //  - and exactly one return statement
     92   return sizeof(K) + sizeof(C) + sizeof(K);
     93 }
     94 constexpr int ForStmt() {
     95   for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}}
     96     return 0;
     97 }
     98 constexpr int VarDecl() {
     99   constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}}
    100   return 0;
    101 }
    102 constexpr int FuncDecl() {
    103   constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}}
    104   return ForwardDecl(42);
    105 }
    106 constexpr int ClassDecl1() {
    107   typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}}
    108   return 0;
    109 }
    110 constexpr int ClassDecl2() {
    111   using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}}
    112   return 0;
    113 }
    114 constexpr int ClassDecl3() {
    115   struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}}
    116   return 0;
    117 }
    118 constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
    119 constexpr int MultiReturn() {
    120   return 0; // expected-note {{return statement}}
    121   return 0; // expected-error {{multiple return statements in constexpr function}}
    122 }
    123 
    124 //  - every constructor call and implicit conversion used in initializing the
    125 //    return value shall be one of those allowed in a constant expression.
    126 //
    127 // We implement the proposed resolution of DR1364 and ignore this bullet.
    128 // However, we implement the spirit of the check as part of the p5 checking that
    129 // a constexpr function must be able to produce a constant expression.
    130 namespace DR1364 {
    131   constexpr int f(int k) {
    132     return k; // ok, even though lvalue-to-rvalue conversion of a function
    133               // parameter is not allowed in a constant expression.
    134   }
    135   int kGlobal; // expected-note {{here}}
    136   constexpr int f() { // expected-error {{constexpr function never produces a constant expression}}
    137     return kGlobal; // expected-note {{read of non-const}}
    138   }
    139 }
    140