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; 26 template<class T> struct ClassTemp {}; 27 28 constexpr Incomplete incomplete = {}; // expected-error {{constexpr variable cannot have non-literal type 'const Incomplete'}} 29 constexpr Incomplete incomplete2[] = {}; // expected-error {{constexpr variable cannot have non-literal type 'Incomplete const[]'}} 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}} 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