Home | History | Annotate | Download | only in basic.types
      1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
      2 
      3 struct NonLiteral { NonLiteral(); };
      4 
      5 // A type is a literal type if it is:
      6 
      7 // - a scalar type
      8 constexpr int f1(double) { return 0; }
      9 
     10 // - a reference type
     11 struct S { S(); };
     12 constexpr int f2(S &) { return 0; }
     13 
     14 // FIXME: I'm not entirely sure whether the following is legal or not...
     15 struct BeingDefined;
     16 extern BeingDefined beingdefined;
     17 struct BeingDefined {
     18   static constexpr BeingDefined& t = beingdefined;
     19 };
     20 
     21 // - a class type that has all of the following properties:
     22 
     23 // (implied) - it is complete
     24 
     25 struct Incomplete; // expected-note 2{{forward declaration of 'Incomplete'}}
     26 template<class T> struct ClassTemp {};
     27 
     28 constexpr Incomplete incomplete = {}; // expected-error {{constexpr variable cannot have non-literal type 'const Incomplete'}} expected-note {{incomplete type 'const Incomplete' is not a literal type}}
     29 constexpr Incomplete incomplete2[] = {}; // expected-error {{constexpr variable cannot have non-literal type 'Incomplete const[]'}} expected-note {{incomplete type 'Incomplete const[]' is not a literal type}}
     30 constexpr ClassTemp<int> classtemplate = {};
     31 constexpr ClassTemp<int> classtemplate2[] = {};
     32 
     33 //  - it has a trivial destructor
     34 struct UserProvDtor {
     35   constexpr int f(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}}
     36   ~UserProvDtor(); // expected-note {{has a user-provided destructor}}
     37 };
     38 
     39 struct NonTrivDtor {
     40   constexpr NonTrivDtor();
     41   constexpr int f(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}}
     42   virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}} expected-note {{because it is virtual}}
     43 };
     44 struct NonTrivDtorBase {
     45   ~NonTrivDtorBase();
     46 };
     47 template<typename T>
     48 struct DerivedFromNonTrivDtor : T { // expected-note {{'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not literal because it has base class 'NonTrivDtorBase' of non-literal type}}
     49   constexpr DerivedFromNonTrivDtor();
     50 };
     51 constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>) { return 0; } // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}}
     52 struct TrivDtor {
     53   constexpr TrivDtor();
     54 };
     55 constexpr int f(TrivDtor) { return 0; }
     56 struct TrivDefaultedDtor {
     57   constexpr TrivDefaultedDtor();
     58   ~TrivDefaultedDtor() = default;
     59 };
     60 constexpr int f(TrivDefaultedDtor) { return 0; }
     61 
     62 //  - it is an aggregate type or has at least one constexpr constructor or
     63 //    constexpr constructor template that is not a copy or move constructor
     64 struct Agg {
     65   int a;
     66   char *b;
     67 };
     68 constexpr int f3(Agg a) { return a.a; }
     69 struct CtorTemplate {
     70   template<typename T> constexpr CtorTemplate(T);
     71 };
     72 struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}}
     73   constexpr CopyCtorOnly(CopyCtorOnly&);
     74   constexpr int f(); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}}
     75 };
     76 struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}}
     77   constexpr MoveCtorOnly(MoveCtorOnly&&);
     78   constexpr int f(); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}}
     79 };
     80 template<typename T>
     81 struct CtorArg {
     82   constexpr CtorArg(T);
     83 };
     84 constexpr int f(CtorArg<int>) { return 0; } // ok
     85 constexpr int f(CtorArg<NonLiteral>) { return 0; } // ok, ctor is still constexpr
     86 // We have a special-case diagnostic for classes with virtual base classes.
     87 struct VBase {};
     88 struct HasVBase : virtual VBase {}; // expected-note 2{{virtual base class declared here}}
     89 struct Derived : HasVBase {
     90   constexpr Derived() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
     91 };
     92 template<typename T> struct DerivedFromVBase : T { // expected-note {{struct with virtual base class is not a literal type}}
     93   constexpr DerivedFromVBase();
     94 };
     95 constexpr int f(DerivedFromVBase<HasVBase>) {} // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}}
     96 template<typename T> constexpr DerivedFromVBase<T>::DerivedFromVBase() : T() {}
     97 constexpr int nVBase = (DerivedFromVBase<HasVBase>(), 0); // expected-error {{constant expression}} expected-note {{cannot construct object of type 'DerivedFromVBase<HasVBase>' with virtual base class in a constant expression}}
     98 
     99 //  - it has all non-static data members and base classes of literal types
    100 struct NonLitMember {
    101   S s; // expected-note {{has data member 's' of non-literal type 'S'}}
    102 };
    103 constexpr int f(NonLitMember) {} // expected-error {{1st parameter type 'NonLitMember' is not a literal type}}
    104 struct NonLitBase :
    105   S { // expected-note {{base class 'S' of non-literal type}}
    106   constexpr NonLitBase();
    107   constexpr int f() { return 0; } // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}}
    108 };
    109 struct LitMemBase : Agg {
    110   Agg agg;
    111 };
    112 template<typename T>
    113 struct MemberType {
    114   T t; // expected-note {{'MemberType<NonLiteral>' is not literal because it has data member 't' of non-literal type 'NonLiteral'}}
    115   constexpr MemberType();
    116 };
    117 constexpr int f(MemberType<int>) { return 0; }
    118 constexpr int f(MemberType<NonLiteral>) { return 0; } // expected-error {{not a literal type}}
    119 
    120 // - an array of literal type
    121 struct ArrGood {
    122   Agg agg[24];
    123   double d[12];
    124   TrivDtor td[3];
    125   TrivDefaultedDtor tdd[3];
    126 };
    127 constexpr int f(ArrGood) { return 0; }
    128 
    129 struct ArrBad {
    130   S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}}
    131 };
    132 constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}}
    133