p10.cpp revision b4e5e286a5cd156247720b1eb204abaa8e09568d
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 2 3struct NonLiteral { NonLiteral(); }; 4 5// A type is a literal type if it is: 6 7// - a scalar type 8constexpr int f1(double); 9 10// - a reference type 11struct S { S(); }; 12constexpr int f2(S &); 13 14// - a class type that has all of the following properties: 15 16// - it has a trivial destructor 17struct UserProvDtor { 18 constexpr UserProvDtor(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}} 19 ~UserProvDtor(); // expected-note {{has a user-provided destructor}} 20}; 21 22struct NonTrivDtor { 23 constexpr NonTrivDtor(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}} 24 virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}} 25}; 26struct NonTrivDtorBase { 27 ~NonTrivDtorBase(); 28}; 29template<typename T> 30struct DerivedFromNonTrivDtor : T { // expected-note {{'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not literal because it has base class 'NonTrivDtorBase' of non-literal type}} 31 constexpr DerivedFromNonTrivDtor(); 32}; 33constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}} 34struct TrivDtor { 35 constexpr TrivDtor(); 36}; 37constexpr int f(TrivDtor); 38struct TrivDefaultedDtor { 39 constexpr TrivDefaultedDtor(); 40 ~TrivDefaultedDtor() = default; 41}; 42constexpr int f(TrivDefaultedDtor); 43 44// - it is an aggregate type or has at least one constexpr constructor or 45// constexpr constructor template that is not a copy or move constructor 46struct Agg { 47 int a; 48 char *b; 49}; 50constexpr int f3(Agg a) { return a.a; } 51struct CtorTemplate { 52 template<typename T> constexpr CtorTemplate(T); 53}; 54struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}} 55 constexpr CopyCtorOnly(CopyCtorOnly&); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}} 56}; 57struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}} 58 constexpr MoveCtorOnly(MoveCtorOnly&&); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}} 59}; 60template<typename T> 61struct CtorArg { // expected-note {{no constexpr constructors other than copy or move constructors}} 62 constexpr CtorArg(T); // expected-note {{constructor template instantiation is not constexpr because 1st parameter type 'NonLiteral' is not a literal type}} 63}; 64constexpr int f(CtorArg<int>); 65constexpr int f(CtorArg<NonLiteral>); // expected-error {{not a literal type}} 66// We have a special-case diagnostic for classes with virtual base classes. 67struct VBase {}; 68struct HasVBase : virtual VBase {}; // expected-note 2{{virtual base class declared here}} 69struct Derived : HasVBase { 70 constexpr Derived(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}} 71}; 72template<typename T> struct DerivedFromVBase : T { // expected-note {{struct with virtual base class is not a literal type}} 73 constexpr DerivedFromVBase(); 74}; 75constexpr int f(DerivedFromVBase<HasVBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}} 76 77// - it has all non-static data members and base classes of literal types 78struct NonLitMember { 79 S s; // expected-note {{has data member 's' of non-literal type 'S'}} 80}; 81constexpr int f(NonLitMember); // expected-error {{1st parameter type 'NonLitMember' is not a literal type}} 82struct NonLitBase : 83 S { // expected-note {{base class 'S' of non-literal type}} 84 constexpr NonLitBase(); // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}} 85}; 86struct LitMemBase : Agg { 87 Agg agg; 88}; 89template<typename T> 90struct MemberType { 91 T t; // expected-note {{'MemberType<NonLiteral>' is not literal because it has data member 't' of non-literal type 'NonLiteral'}} 92 constexpr MemberType(); 93}; 94constexpr int f(MemberType<int>); 95constexpr int f(MemberType<NonLiteral>); // expected-error {{not a literal type}} 96 97// - an array of literal type 98struct ArrGood { 99 Agg agg[24]; 100 double d[12]; 101 TrivDtor td[3]; 102 TrivDefaultedDtor tdd[3]; 103}; 104constexpr int f(ArrGood); 105 106struct ArrBad { 107 S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}} 108}; 109constexpr int f(ArrBad); // expected-error {{1st parameter type 'ArrBad' is not a literal type}} 110