Clang Project

clang_source_code/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
1// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions -Werror=c++2a-extensions %s
2// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y -Werror=c++2a-extensions %s
3// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++2a -DCXX1Y -DCXX2A %s
4
5namespace N {
6  typedef char C;
7}
8
9namespace M {
10  typedef double D;
11}
12
13struct NonLiteral { // expected-note 3{{no constexpr constructors}}
14  NonLiteral() {}
15  NonLiteral(int) {}
16};
17struct Literal {
18  constexpr Literal() {}
19  operator int() const { return 0; }
20};
21
22struct S {
23  virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}}
24};
25struct SS : S {
26  int ImplicitlyVirtual() const;
27};
28
29// The definition of a constexpr function shall satisfy the following
30// constraints:
31struct T : SS, NonLiteral {
32  constexpr T();
33  constexpr int f() const;
34
35  //  - it shall not be virtual;
36  virtual constexpr int ExplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
37
38  constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
39
40  virtual constexpr int OutOfLineVirtual() const; // expected-error {{virtual function cannot be constexpr}}
41
42  //  - its return type shall be a literal type;
43  constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
44  constexpr void VoidReturn() const { return; }
45#ifndef CXX1Y
46  // expected-error@-2 {{constexpr function's return type 'void' is not a literal type}}
47#endif
48  constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}}
49  typedef NonLiteral F() const;
50  constexpr F NonLiteralReturn2; // ok until definition
51
52  //  - each of its parameter types shall be a literal type;
53  constexpr int NonLiteralParam(NonLiteral) const { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
54  typedef int G(NonLiteral) const;
55  constexpr G NonLiteralParam2; // ok until definition
56
57  //  - its function-body shall be = delete, = default,
58  constexpr int Deleted() const = delete;
59  // It's not possible for the function-body to legally be "= default" here
60  // (that is, for a non-constructor function) in C++11.
61  // Other than constructors, only the copy- and move-assignment operators and
62  // destructor can be defaulted. Destructors can't be constexpr since they
63  // don't have a literal return type. Defaulted assignment operators can't be
64  // constexpr since they can't be const.
65  constexpr T &operator=(const T&) = default;
66#ifndef CXX1Y
67  // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
68  // expected-warning@-3 {{C++14}}
69#else
70  // expected-error@-5 {{defaulted definition of copy assignment operator is not constexpr}}
71#endif
72};
73
74constexpr int T::OutOfLineVirtual() const { return 0; }
75#ifdef CXX1Y
76struct T2 {
77  int n = 0;
78  constexpr T2 &operator=(const T2&) = default; // ok
79};
80struct T3 {
81  constexpr T3 &operator=(const T3&) const = default;
82#ifndef CXX2A
83  // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}}
84#else
85  // expected-warning@-4 {{explicitly defaulted copy assignment operator is implicitly deleted}}
86  // expected-note@-5 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
87#endif
88};
89#endif
90struct U {
91  constexpr U SelfReturn() const;
92  constexpr int SelfParam(U) const;
93};
94
95struct V : virtual U { // expected-note {{here}}
96  constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
97};
98
99//  or a compound-statememt that contains only [CXX11]
100constexpr int AllowedStmtsCXX11() {
101  //  - null statements
102  ;
103
104  //  - static_assert-declarations
105  static_assert(true, "the impossible happened!");
106
107  //  - typedef declarations and alias-declarations that do not define classes
108  //    or enumerations
109  typedef int I;
110  typedef struct S T;
111  using J = int;
112  using K = int[sizeof(I) + sizeof(J)];
113  // Note, the standard requires we reject this.
114  struct U;
115
116  //  - using-declarations
117  using N::C;
118
119  //  - using-directives
120  using namespace N;
121
122  //  - and exactly one return statement
123  return sizeof(K) + sizeof(C) + sizeof(K);
124}
125
126//  or a compound-statement that does not contain [CXX1Y]
127constexpr int DisallowedStmtsCXX1Y_1() {
128  //  - an asm-definition
129  asm("int3"); // expected-error {{statement not allowed in constexpr function}}
130  return 0;
131}
132constexpr int DisallowedStmtsCXX1Y_2() {
133  //  - a goto statement
134  goto x; // expected-error {{statement not allowed in constexpr function}}
135x:
136  return 0;
137}
138constexpr int DisallowedStmtsCXX1Y_2_1() {
139  try {
140    return 0;
141  } catch (...) {
142  merp: goto merp; // expected-error {{statement not allowed in constexpr function}}
143  }
144}
145constexpr int DisallowedStmtsCXX1Y_3() {
146  //  - a try-block,
147  try {} catch (...) {}
148#ifndef CXX2A
149  // expected-error@-2 {{use of this statement in a constexpr function is a C++2a extension}}
150#ifndef CXX1Y
151  // expected-error@-4 {{use of this statement in a constexpr function is a C++14 extension}}
152#endif
153#endif
154  return 0;
155}
156constexpr int DisallowedStmtsCXX1Y_4() {
157  //  - a definition of a variable of non-literal type
158  NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}}
159  return 0;
160}
161constexpr int DisallowedStmtsCXX1Y_5() {
162  //  - a definition of a variable of static storage duration
163  static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}}
164  return n;
165}
166constexpr int DisallowedStmtsCXX1Y_6() {
167  //  - a definition of a variable of thread storage duration
168  thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}}
169  return n;
170}
171constexpr int DisallowedStmtsCXX1Y_7() {
172  //  - a definition of a variable for which no initialization is performed
173  int n; // expected-error {{variables defined in a constexpr function must be initialized}}
174  return 0;
175}
176
177constexpr int ForStmt() {
178  for (int n = 0; n < 10; ++n)
179#ifndef CXX1Y
180  // expected-error@-2 {{statement not allowed in constexpr function}}
181#endif
182    return 0;
183}
184constexpr int VarDecl() {
185  int a = 0;
186#ifndef CXX1Y
187  // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
188#endif
189  return 0;
190}
191constexpr int ConstexprVarDecl() {
192  constexpr int a = 0;
193#ifndef CXX1Y
194  // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
195#endif
196  return 0;
197}
198constexpr int VarWithCtorDecl() {
199  Literal a;
200#ifndef CXX1Y
201  // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
202#endif
203  return 0;
204}
205NonLiteral nl;
206constexpr NonLiteral &ExternNonLiteralVarDecl() {
207  extern NonLiteral nl;
208#ifndef CXX1Y
209  // expected-error@-2 {{variable declaration in a constexpr function is a C++14 extension}}
210#endif
211  return nl;
212}
213static_assert(&ExternNonLiteralVarDecl() == &nl, "");
214constexpr int FuncDecl() {
215  constexpr int ForwardDecl(int);
216#ifndef CXX1Y
217  // expected-error@-2 {{use of this statement in a constexpr function is a C++14 extension}}
218#endif
219  return ForwardDecl(42);
220}
221constexpr int ClassDecl1() {
222  typedef struct { } S1;
223#ifndef CXX1Y
224  // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}}
225#endif
226  return 0;
227}
228constexpr int ClassDecl2() {
229  using S2 = struct { };
230#ifndef CXX1Y
231  // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}}
232#endif
233  return 0;
234}
235constexpr int ClassDecl3() {
236  struct S3 { };
237#ifndef CXX1Y
238  // expected-error@-2 {{type definition in a constexpr function is a C++14 extension}}
239#endif
240  return 0;
241}
242constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
243constexpr int MultiReturn() {
244  return 0;
245  return 0;
246#ifndef CXX1Y
247  // expected-error@-2 {{multiple return statements in constexpr function}}
248  // expected-note@-4 {{return statement}}
249#endif
250}
251
252//  - every constructor call and implicit conversion used in initializing the
253//    return value shall be one of those allowed in a constant expression.
254//
255// We implement the proposed resolution of DR1364 and ignore this bullet.
256// However, we implement the spirit of the check as part of the p5 checking that
257// a constexpr function must be able to produce a constant expression.
258namespace DR1364 {
259  constexpr int f(int k) {
260    return k; // ok, even though lvalue-to-rvalue conversion of a function
261              // parameter is not allowed in a constant expression.
262  }
263  int kGlobal; // expected-note {{here}}
264  constexpr int f() { // expected-error {{constexpr function never produces a constant expression}}
265    return kGlobal; // expected-note {{read of non-const}}
266  }
267}
268
269namespace rdar13584715 {
270  typedef __PTRDIFF_TYPE__ ptrdiff_t;
271
272  template<typename T> struct X {
273    static T value() {};
274  };
275
276  void foo(ptrdiff_t id) {
277    switch (id) {
278    case reinterpret_cast<ptrdiff_t>(&X<long>::value):  // expected-error{{case value is not a constant expression}} \
279      // expected-note{{reinterpret_cast is not allowed in a constant expression}}
280      break;
281    }
282  }
283}
284
285namespace std_example {
286  constexpr int square(int x) {
287    return x * x;
288  }
289  constexpr long long_max() {
290    return 2147483647;
291  }
292  constexpr int abs(int x) {
293    if (x < 0)
294#ifndef CXX1Y
295      // expected-error@-2 {{C++14}}
296#endif
297      x = -x;
298    return x;
299  }
300  constexpr int first(int n) {
301    static int value = n; // expected-error {{static variable not permitted}}
302    return value;
303  }
304  constexpr int uninit() {
305    int a; // expected-error {{must be initialized}}
306    return a;
307  }
308  constexpr int prev(int x) {
309    return --x;
310  }
311#ifndef CXX1Y
312  // expected-error@-4 {{never produces a constant expression}}
313  // expected-note@-4 {{subexpression}}
314#endif
315  constexpr int g(int x, int n) {
316    int r = 1;
317    while (--n > 0) r *= x;
318    return r;
319  }
320#ifndef CXX1Y
321    // expected-error@-5 {{C++14}}
322    // expected-error@-5 {{statement not allowed}}
323#endif
324}
325