p3.cpp revision 840462670ba7a6bc26265a2306b35f2f0f01f51c
1// RUN: %clang_cc1 -verify -std=c++11 %s
2
3namespace N {
4  typedef char C;
5}
6
7namespace M {
8  typedef double D;
9}
10
11struct NonLiteral { // expected-note 2{{no constexpr constructors}}
12  NonLiteral() {}
13  NonLiteral(int) {}
14};
15struct Literal {
16  constexpr Literal() {}
17  operator int() const { return 0; }
18};
19
20struct S {
21  virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}}
22};
23struct SS : S {
24  int ImplicitlyVirtual() const;
25};
26
27// The definition of a constexpr function shall satisfy the following
28// constraints:
29struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}}
30  constexpr T();
31  constexpr int f() const; // expected-error {{non-literal type 'T' cannot have constexpr members}}
32
33  //  - it shall not be virtual;
34  virtual constexpr int ExplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
35
36  constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
37
38  //  - its return type shall be a literal type;
39  constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
40  constexpr void VoidReturn() const { return; } // expected-error {{constexpr function's return type 'void' is not a literal type}}
41  constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}}
42  typedef NonLiteral F() const;
43  constexpr F NonLiteralReturn2; // ok until definition
44
45  //  - each of its parameter types shall be a literal type;
46  constexpr int NonLiteralParam(NonLiteral) const { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
47  typedef int G(NonLiteral) const;
48  constexpr G NonLiteralParam2; // ok until definition
49
50  //  - its function-body shall be = delete, = default,
51  constexpr int Deleted() const = delete;
52  // It's not possible for the function-body to legally be "= default" here.
53  // Other than constructors, only the copy- and move-assignment operators and
54  // destructor can be defaulted. Destructors can't be constexpr since they
55  // don't have a literal return type. Defaulted assignment operators can't be
56  // constexpr since they can't be const.
57  constexpr T &operator=(const T&) = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} expected-warning {{C++1y}}
58};
59struct U {
60  constexpr U SelfReturn() const;
61  constexpr int SelfParam(U) const;
62};
63
64struct V : virtual U { // expected-note {{here}}
65  constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
66};
67
68//  or a compound-statememt that contains only
69constexpr int AllowedStmts() {
70  //  - null statements
71  ;
72
73  //  - static_assert-declarations
74  static_assert(true, "the impossible happened!");
75
76  //  - typedef declarations and alias-declarations that do not define classes
77  //    or enumerations
78  typedef int I;
79  typedef struct S T;
80  using J = int;
81  using K = int[sizeof(I) + sizeof(J)];
82  // Note, the standard requires we reject this.
83  struct U;
84
85  //  - using-declarations
86  using N::C;
87
88  //  - using-directives
89  using namespace N;
90
91  //  - and exactly one return statement
92  return sizeof(K) + sizeof(C) + sizeof(K);
93}
94constexpr int ForStmt() {
95  for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}}
96    return 0;
97}
98constexpr int VarDecl() {
99  constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}}
100  return 0;
101}
102constexpr int FuncDecl() {
103  constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}}
104  return ForwardDecl(42);
105}
106constexpr int ClassDecl1() {
107  typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}}
108  return 0;
109}
110constexpr int ClassDecl2() {
111  using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}}
112  return 0;
113}
114constexpr int ClassDecl3() {
115  struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}}
116  return 0;
117}
118constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
119constexpr int MultiReturn() {
120  return 0; // expected-note {{return statement}}
121  return 0; // expected-error {{multiple return statements in constexpr function}}
122}
123
124//  - every constructor call and implicit conversion used in initializing the
125//    return value shall be one of those allowed in a constant expression.
126//
127// We implement the proposed resolution of DR1364 and ignore this bullet.
128// However, we implement the spirit of the check as part of the p5 checking that
129// a constexpr function must be able to produce a constant expression.
130namespace DR1364 {
131  constexpr int f(int k) {
132    return k; // ok, even though lvalue-to-rvalue conversion of a function
133              // parameter is not allowed in a constant expression.
134  }
135  int kGlobal; // expected-note {{here}}
136  constexpr int f() { // expected-error {{constexpr function never produces a constant expression}}
137    return kGlobal; // expected-note {{read of non-const}}
138  }
139}
140
141namespace rdar13584715 {
142  typedef __PTRDIFF_TYPE__ ptrdiff_t;
143
144  template<typename T> struct X {
145    static T value() {};
146  };
147
148  void foo(ptrdiff_t id) {
149    switch (id) {
150    case reinterpret_cast<ptrdiff_t>(&X<long>::value):  // expected-error{{case value is not a constant expression}} \
151      // expected-note{{reinterpret_cast is not allowed in a constant expression}}
152      break;
153    }
154  }
155}
156