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 ~UserProvDtor(); // expected-note {{has a user-provided destructor}} 42 }; 43 constexpr int f(UserProvDtor) { return 0; } // expected-error {{'UserProvDtor' is not a literal type}} 44 struct NonTrivDtor { 45 constexpr NonTrivDtor(); 46 virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}} expected-note {{because it is virtual}} 47 }; 48 constexpr int f(NonTrivDtor) { return 0; } // expected-error {{'NonTrivDtor' is not a literal type}} 49 struct NonTrivDtorBase { 50 ~NonTrivDtorBase(); 51 }; 52 template<typename T> 53 struct DerivedFromNonTrivDtor : T { // expected-note {{'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not literal because it has base class 'NonTrivDtorBase' of non-literal type}} 54 constexpr DerivedFromNonTrivDtor(); 55 }; 56 constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>) { return 0; } // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}} 57 struct TrivDtor { 58 constexpr TrivDtor(); 59 }; 60 constexpr int f(TrivDtor) { return 0; } 61 struct TrivDefaultedDtor { 62 constexpr TrivDefaultedDtor(); 63 ~TrivDefaultedDtor() = default; 64 }; 65 constexpr int f(TrivDefaultedDtor) { return 0; } 66 67 // - it is an aggregate type or has at least one constexpr constructor or 68 // constexpr constructor template that is not a copy or move constructor 69 struct Agg { 70 int a; 71 char *b; 72 }; 73 constexpr int f3(Agg a) { return a.a; } 74 struct CtorTemplate { 75 template<typename T> constexpr CtorTemplate(T); 76 }; 77 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}} 78 constexpr CopyCtorOnly(CopyCtorOnly&); 79 }; 80 constexpr int f(CopyCtorOnly) { return 0; } // expected-error {{'CopyCtorOnly' is not a literal type}} 81 struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}} 82 constexpr MoveCtorOnly(MoveCtorOnly&&); 83 }; 84 constexpr int f(MoveCtorOnly) { return 0; } // expected-error {{'MoveCtorOnly' is not a literal type}} 85 template<typename T> 86 struct CtorArg { 87 constexpr CtorArg(T); 88 }; 89 constexpr int f(CtorArg<int>) { return 0; } // ok 90 constexpr int f(CtorArg<NonLiteral>) { return 0; } // ok, ctor is still constexpr 91 // We have a special-case diagnostic for classes with virtual base classes. 92 struct VBase {}; 93 struct HasVBase : virtual VBase {}; // expected-note 2{{virtual base class declared here}} 94 struct Derived : HasVBase { 95 constexpr Derived() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}} 96 }; 97 template<typename T> struct DerivedFromVBase : T { // expected-note {{struct with virtual base class is not a literal type}} 98 constexpr DerivedFromVBase(); 99 }; 100 constexpr int f(DerivedFromVBase<HasVBase>) {} // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}} 101 template<typename T> constexpr DerivedFromVBase<T>::DerivedFromVBase() : T() {} 102 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}} 103 104 // - it has all non-static data members and base classes of literal types 105 struct NonLitMember { 106 S s; // expected-note {{has data member 's' of non-literal type 'S'}} 107 }; 108 constexpr int f(NonLitMember) {} // expected-error {{1st parameter type 'NonLitMember' is not a literal type}} 109 struct NonLitBase : 110 S { // expected-note {{base class 'S' of non-literal type}} 111 constexpr NonLitBase(); 112 }; 113 constexpr int f(NonLitBase) { return 0; } // expected-error {{'NonLitBase' is not a literal type}} 114 struct LitMemBase : Agg { 115 Agg agg; 116 }; 117 template<typename T> 118 struct MemberType { 119 T t; // expected-note {{'MemberType<NonLiteral>' is not literal because it has data member 't' of non-literal type 'NonLiteral'}} 120 constexpr MemberType(); 121 }; 122 constexpr int f(MemberType<int>) { return 0; } 123 constexpr int f(MemberType<NonLiteral>) { return 0; } // expected-error {{not a literal type}} 124 125 // - an array of literal type [C++1y] other than an array of runtime bound 126 struct ArrGood { 127 Agg agg[24]; 128 double d[12]; 129 TrivDtor td[3]; 130 TrivDefaultedDtor tdd[3]; 131 }; 132 constexpr int f(ArrGood) { return 0; } 133 134 struct ArrBad { 135 S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}} 136 }; 137 constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}} 138 139 constexpr int arb(int n) { 140 int a[n]; // expected-error {{variable of non-literal type 'int [n]' cannot be defined in a constexpr function}} 141 } 142 constexpr long Overflow[ // expected-error {{constexpr variable cannot have non-literal type 'long const[(1 << 30) << 2]'}} 143 (1 << 30) << 2]{}; // expected-warning {{requires 34 bits to represent}} 144 145 namespace inherited_ctor { 146 struct A { constexpr A(int); }; 147 struct B : A { 148 B(); 149 using A::A; 150 }; 151 constexpr int f(B) { return 0; } // ok 152 153 struct C { constexpr C(int); }; 154 struct D : C { // expected-note {{because}} 155 D(int); 156 using C::C; 157 }; 158 constexpr int f(D) { return 0; } // expected-error {{not a literal type}} 159 160 // This one is a bit odd: F inherits E's default constructor, which is 161 // constexpr. Because F has a constructor of its own, it doesn't declare a 162 // default constructor hiding E's one. 163 struct E {}; 164 struct F : E { 165 F(int); 166 using E::E; 167 }; 168 constexpr int f(F) { return 0; } 169 170 // FIXME: Is this really the right behavior? We presumably should be checking 171 // whether the inherited constructor would be a copy or move constructor for 172 // the derived class, not for the base class. 173 struct G { constexpr G(const G&); }; 174 struct H : G { // expected-note {{because}} 175 using G::G; 176 }; 177 constexpr int f(H) { return 0; } // expected-error {{not a literal type}} 178 179 struct J; 180 struct I { constexpr I(const J&); }; 181 struct J : I { 182 using I::I; 183 }; 184 constexpr int f(J) { return 0; } 185 } 186