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 
4 namespace N {
5   typedef char C;
6 }
7 
8 namespace M {
9   typedef double D;
10 }
11 
12 struct NonLiteral { // expected-note 3{{no constexpr constructors}}
13   NonLiteral() {}
14   NonLiteral(int) {}
15 };
16 struct Literal {
17   constexpr Literal() {}
18   operator int() const { return 0; }
19 };
20 
21 struct S {
22   virtual int ImplicitlyVirtual() const = 0; // expected-note {{overridden virtual function}}
23 };
24 struct SS : S {
25   int ImplicitlyVirtual() const;
26 };
27 
28 // The definition of a constexpr function shall satisfy the following
29 // constraints:
30 struct 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
71 struct T2 {
72   int n = 0;
73   constexpr T2 &operator=(const T2&) = default; // ok
74 };
75 struct 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
80 struct U {
81   constexpr U SelfReturn() const;
82   constexpr int SelfParam(U) const;
83 };
84 
85 struct 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]
90 constexpr 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]
117 constexpr int DisallowedStmtsCXX1Y_1() {
118   //  - an asm-definition
119   asm("int3"); // expected-error {{statement not allowed in constexpr function}}
120   return 0;
121 }
122 constexpr int DisallowedStmtsCXX1Y_2() {
123   //  - a goto statement
124   goto x; // expected-error {{statement not allowed in constexpr function}}
125 x:
126   return 0;
127 }
128 constexpr int DisallowedStmtsCXX1Y_3() {
129   //  - a try-block,
130   try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}}
131   return 0;
132 }
133 constexpr 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 }
138 constexpr 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 }
143 constexpr 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 }
148 constexpr 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 
154 constexpr 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 }
161 constexpr 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 }
168 constexpr 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 }
175 constexpr 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 }
182 NonLiteral nl;
183 constexpr 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 }
190 static_assert(&ExternNonLiteralVarDecl() == &nl, "");
191 constexpr 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 }
198 constexpr 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 }
205 constexpr 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 }
212 constexpr 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 }
219 constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
220 constexpr 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.
235 namespace 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 
246 namespace 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 
262 namespace 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