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