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}}
NonLiteralNonLiteral13 NonLiteral() {}
NonLiteralNonLiteral14 NonLiteral(int) {}
15 };
16 struct Literal {
LiteralLiteral17 constexpr Literal() {}
operator intLiteral18 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;
ExplicitlyVirtualT35 virtual constexpr int ExplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
36
ImplicitlyVirtualT37 constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
38
39 // - its return type shall be a literal type;
NonLiteralReturnT40 constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
VoidReturnT41 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;
NonLiteralParamT50 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}}
FV86 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]
AllowedStmtsCXX11()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]
DisallowedStmtsCXX1Y_1()117 constexpr int DisallowedStmtsCXX1Y_1() {
118 // - an asm-definition
119 asm("int3"); // expected-error {{statement not allowed in constexpr function}}
120 return 0;
121 }
DisallowedStmtsCXX1Y_2()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 }
DisallowedStmtsCXX1Y_3()128 constexpr int DisallowedStmtsCXX1Y_3() {
129 // - a try-block,
130 try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}}
131 return 0;
132 }
DisallowedStmtsCXX1Y_4()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 }
DisallowedStmtsCXX1Y_5()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 }
DisallowedStmtsCXX1Y_6()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 }
DisallowedStmtsCXX1Y_7()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
ForStmt()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 }
VarDecl()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 }
ConstexprVarDecl()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 }
VarWithCtorDecl()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;
ExternNonLiteralVarDecl()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, "");
FuncDecl()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 }
ClassDecl1()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 }
ClassDecl2()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 }
ClassDecl3()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 }
NoReturn()219 constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
MultiReturn()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 {
f(int k)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}}
f()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 {
valuerdar13584715::X250 static T value() {};
251 };
252
foo(ptrdiff_t id)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 {
square(int x)263 constexpr int square(int x) {
264 return x * x;
265 }
long_max()266 constexpr long long_max() {
267 return 2147483647;
268 }
abs(int x)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 }
first(int n)277 constexpr int first(int n) {
278 static int value = n; // expected-error {{static variable not permitted}}
279 return value;
280 }
uninit()281 constexpr int uninit() {
282 int a; // expected-error {{must be initialized}}
283 return a;
284 }
prev(int x)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
g(int x,int n)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