1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1y %s -DCXX1Y
3
4struct NonLiteral { NonLiteral(); };
5
6// A type is a literal type if it is:
7
8// [C++1y] - void
9constexpr void f() {}
10#ifndef CXX1Y
11// expected-error@-2 {{'void' is not a literal type}}
12#endif
13
14// - a scalar type
15constexpr int f1(double) { return 0; }
16
17// - a reference type
18struct S { S(); };
19constexpr int f2(S &) { return 0; }
20
21struct BeingDefined;
22extern BeingDefined beingdefined;
23struct 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
31struct Incomplete; // expected-note 2{{forward declaration of 'Incomplete'}}
32template<class T> struct ClassTemp {};
33
34constexpr Incomplete incomplete = {}; // expected-error {{constexpr variable cannot have non-literal type 'const Incomplete'}} expected-note {{incomplete type 'const Incomplete' is not a literal type}}
35constexpr Incomplete incomplete2[] = {}; // expected-error {{constexpr variable cannot have non-literal type 'Incomplete const[]'}} expected-note {{incomplete type 'Incomplete const[]' is not a literal type}}
36constexpr ClassTemp<int> classtemplate = {};
37constexpr ClassTemp<int> classtemplate2[] = {};
38
39//  - it has a trivial destructor
40struct 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
45struct 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};
50struct NonTrivDtorBase {
51  ~NonTrivDtorBase();
52};
53template<typename T>
54struct DerivedFromNonTrivDtor : T { // expected-note {{'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not literal because it has base class 'NonTrivDtorBase' of non-literal type}}
55  constexpr DerivedFromNonTrivDtor();
56};
57constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>) { return 0; } // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}}
58struct TrivDtor {
59  constexpr TrivDtor();
60};
61constexpr int f(TrivDtor) { return 0; }
62struct TrivDefaultedDtor {
63  constexpr TrivDefaultedDtor();
64  ~TrivDefaultedDtor() = default;
65};
66constexpr 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
70struct Agg {
71  int a;
72  char *b;
73};
74constexpr int f3(Agg a) { return a.a; }
75struct CtorTemplate {
76  template<typename T> constexpr CtorTemplate(T);
77};
78struct 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};
82struct 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};
86template<typename T>
87struct CtorArg {
88  constexpr CtorArg(T);
89};
90constexpr int f(CtorArg<int>) { return 0; } // ok
91constexpr int f(CtorArg<NonLiteral>) { return 0; } // ok, ctor is still constexpr
92// We have a special-case diagnostic for classes with virtual base classes.
93struct VBase {};
94struct HasVBase : virtual VBase {}; // expected-note 2{{virtual base class declared here}}
95struct Derived : HasVBase {
96  constexpr Derived() {} // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
97};
98template<typename T> struct DerivedFromVBase : T { // expected-note {{struct with virtual base class is not a literal type}}
99  constexpr DerivedFromVBase();
100};
101constexpr int f(DerivedFromVBase<HasVBase>) {} // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}}
102template<typename T> constexpr DerivedFromVBase<T>::DerivedFromVBase() : T() {}
103constexpr 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
106struct NonLitMember {
107  S s; // expected-note {{has data member 's' of non-literal type 'S'}}
108};
109constexpr int f(NonLitMember) {} // expected-error {{1st parameter type 'NonLitMember' is not a literal type}}
110struct 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};
115struct LitMemBase : Agg {
116  Agg agg;
117};
118template<typename T>
119struct 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};
123constexpr int f(MemberType<int>) { return 0; }
124constexpr 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
127struct ArrGood {
128  Agg agg[24];
129  double d[12];
130  TrivDtor td[3];
131  TrivDefaultedDtor tdd[3];
132};
133constexpr int f(ArrGood) { return 0; }
134
135struct ArrBad {
136  S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}}
137};
138constexpr int f(ArrBad) { return 0; } // expected-error {{1st parameter type 'ArrBad' is not a literal type}}
139
140constexpr 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