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