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