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
f()9 constexpr void f() {}
10 #ifndef CXX1Y
11 // expected-error@-2 {{'void' is not a literal type}}
12 #endif
13 
14 // - a scalar type
f1(double)15 constexpr int f1(double) { return 0; }
16 
17 // - a reference type
18 struct S { S(); };
f2(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 };
f(UserProvDtor)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 };
f(NonTrivDtor)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 };
f(DerivedFromNonTrivDtor<NonTrivDtorBase>)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 };
f(TrivDtor)60 constexpr int f(TrivDtor) { return 0; }
61 struct TrivDefaultedDtor {
62   constexpr TrivDefaultedDtor();
63   ~TrivDefaultedDtor() = default;
64 };
f(TrivDefaultedDtor)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 };
f3(Agg a)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 };
f(CopyCtorOnly)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 };
f(MoveCtorOnly)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 };
f(CtorArg<int>)89 constexpr int f(CtorArg<int>) { return 0; } // ok
f(CtorArg<NonLiteral>)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 {
DerivedDerived95   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 };
f(DerivedFromVBase<HasVBase>)100 constexpr int f(DerivedFromVBase<HasVBase>) {} // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}}
DerivedFromVBase()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 };
f(NonLitMember)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 };
f(NonLitBase)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 };
f(MemberType<int>)122 constexpr int f(MemberType<int>) { return 0; }
f(MemberType<NonLiteral>)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 };
f(ArrGood)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 };
f(ArrBad)137 constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}}
138 
arb(int n)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