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 
5 namespace N {
6   typedef char C;
7 }
8 
9 namespace M {
10   typedef double D;
11 }
12 
13 struct NonLiteral { // expected-note 3{{no constexpr constructors}}
14   NonLiteral() {}
15   NonLiteral(int) {}
16 };
17 struct Literal {
18   constexpr Literal() {}
19   operator int() const { return 0; }
20 };
21 
22 struct S {
23   virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}}
24 };
25 struct SS : S {
26   int ImplicitlyVirtual() const;
27 };
28 
29 // The definition of a constexpr function shall satisfy the following
30 // constraints:
31 struct 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 
74 constexpr int T::OutOfLineVirtual() const { return 0; }
75 #ifdef CXX1Y
76 struct T2 {
77   int n = 0;
78   constexpr T2 &operator=(const T2&) = default; // ok
79 };
80 struct 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
90 struct U {
91   constexpr U SelfReturn() const;
92   constexpr int SelfParam(U) const;
93 };
94 
95 struct 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]
100 constexpr 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]
127 constexpr int DisallowedStmtsCXX1Y_1() {
128   //  - an asm-definition
129   asm("int3"); // expected-error {{statement not allowed in constexpr function}}
130   return 0;
131 }
132 constexpr int DisallowedStmtsCXX1Y_2() {
133   //  - a goto statement
134   goto x; // expected-error {{statement not allowed in constexpr function}}
135 x:
136   return 0;
137 }
138 constexpr 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 }
145 constexpr 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 }
156 constexpr 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 }
161 constexpr 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 }
166 constexpr 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 }
171 constexpr 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 
177 constexpr 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 }
184 constexpr 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 }
191 constexpr 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 }
198 constexpr 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 }
205 NonLiteral nl;
206 constexpr 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 }
213 static_assert(&ExternNonLiteralVarDecl() == &nl, "");
214 constexpr 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 }
221 constexpr 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 }
228 constexpr 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 }
235 constexpr 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 }
242 constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
243 constexpr 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.
258 namespace 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 
269 namespace 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 
285 namespace 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