p10.cpp revision b4e5e286a5cd156247720b1eb204abaa8e09568d
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2
3struct NonLiteral { NonLiteral(); };
4
5// A type is a literal type if it is:
6
7// - a scalar type
8constexpr int f1(double);
9
10// - a reference type
11struct S { S(); };
12constexpr int f2(S &);
13
14// - a class type that has all of the following properties:
15
16//  - it has a trivial destructor
17struct UserProvDtor {
18  constexpr UserProvDtor(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}}
19  ~UserProvDtor(); // expected-note {{has a user-provided destructor}}
20};
21
22struct NonTrivDtor {
23  constexpr NonTrivDtor(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}}
24  virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}}
25};
26struct NonTrivDtorBase {
27  ~NonTrivDtorBase();
28};
29template<typename T>
30struct DerivedFromNonTrivDtor : T { // expected-note {{'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not literal because it has base class 'NonTrivDtorBase' of non-literal type}}
31  constexpr DerivedFromNonTrivDtor();
32};
33constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}}
34struct TrivDtor {
35  constexpr TrivDtor();
36};
37constexpr int f(TrivDtor);
38struct TrivDefaultedDtor {
39  constexpr TrivDefaultedDtor();
40  ~TrivDefaultedDtor() = default;
41};
42constexpr int f(TrivDefaultedDtor);
43
44//  - it is an aggregate type or has at least one constexpr constructor or
45//    constexpr constructor template that is not a copy or move constructor
46struct Agg {
47  int a;
48  char *b;
49};
50constexpr int f3(Agg a) { return a.a; }
51struct CtorTemplate {
52  template<typename T> constexpr CtorTemplate(T);
53};
54struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}}
55  constexpr CopyCtorOnly(CopyCtorOnly&); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}}
56};
57struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}}
58  constexpr MoveCtorOnly(MoveCtorOnly&&); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}}
59};
60template<typename T>
61struct CtorArg { // expected-note {{no constexpr constructors other than copy or move constructors}}
62  constexpr CtorArg(T); // expected-note {{constructor template instantiation is not constexpr because 1st parameter type 'NonLiteral' is not a literal type}}
63};
64constexpr int f(CtorArg<int>);
65constexpr int f(CtorArg<NonLiteral>); // expected-error {{not a literal type}}
66// We have a special-case diagnostic for classes with virtual base classes.
67struct VBase {};
68struct HasVBase : virtual VBase {}; // expected-note 2{{virtual base class declared here}}
69struct Derived : HasVBase {
70  constexpr Derived(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
71};
72template<typename T> struct DerivedFromVBase : T { // expected-note {{struct with virtual base class is not a literal type}}
73  constexpr DerivedFromVBase();
74};
75constexpr int f(DerivedFromVBase<HasVBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}}
76
77//  - it has all non-static data members and base classes of literal types
78struct NonLitMember {
79  S s; // expected-note {{has data member 's' of non-literal type 'S'}}
80};
81constexpr int f(NonLitMember); // expected-error {{1st parameter type 'NonLitMember' is not a literal type}}
82struct NonLitBase :
83  S { // expected-note {{base class 'S' of non-literal type}}
84  constexpr NonLitBase(); // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}}
85};
86struct LitMemBase : Agg {
87  Agg agg;
88};
89template<typename T>
90struct MemberType {
91  T t; // expected-note {{'MemberType<NonLiteral>' is not literal because it has data member 't' of non-literal type 'NonLiteral'}}
92  constexpr MemberType();
93};
94constexpr int f(MemberType<int>);
95constexpr int f(MemberType<NonLiteral>); // expected-error {{not a literal type}}
96
97// - an array of literal type
98struct ArrGood {
99  Agg agg[24];
100  double d[12];
101  TrivDtor td[3];
102  TrivDefaultedDtor tdd[3];
103};
104constexpr int f(ArrGood);
105
106struct ArrBad {
107  S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}}
108};
109constexpr int f(ArrBad); // expected-error {{1st parameter type 'ArrBad' is not a literal type}}
110