[mlir][acc] Introduce MappableType interface (#122146)
[llvm-project.git] / clang / test / CXX / dcl.dcl / dcl.spec / dcl.constexpr / p3.cpp
blob51990ee4341d29b5d1d0502d7d609275d3ee2bde
1 // RUN: %clang_cc1 -fcxx-exceptions -verify=expected,beforecxx14,beforecxx20,beforecxx23 -std=c++11 %s
2 // RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,beforecxx20,beforecxx23,cxx14_20 -std=c++14 %s
3 // RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,aftercxx20,beforecxx23,cxx14_20 -std=c++20 %s
4 // RUN: %clang_cc1 -fcxx-exceptions -verify=expected,aftercxx14,aftercxx20 -std=c++23 %s
6 namespace N {
7 typedef char C;
10 namespace M {
11 typedef double D;
14 struct NonLiteral { // beforecxx23-note 2{{no constexpr constructors}}
15 NonLiteral() {}
16 NonLiteral(int) {}
18 struct Literal {
19 constexpr Literal() {}
20 operator int() const { return 0; }
23 struct S {
24 virtual int ImplicitlyVirtual() const = 0; // beforecxx20-note {{overridden virtual function}}
26 struct SS : S {
27 int ImplicitlyVirtual() const;
30 // The definition of a constexpr function shall satisfy the following
31 // constraints:
32 struct T : SS, NonLiteral {
33 constexpr T();
34 constexpr int f() const;
36 // - it shall not be virtual; [until C++20]
37 virtual constexpr int ExplicitlyVirtual() const { return 0; } // beforecxx20-error {{virtual function cannot be constexpr}}
39 constexpr int ImplicitlyVirtual() const { return 0; } // beforecxx20-error {{virtual function cannot be constexpr}}
41 virtual constexpr int OutOfLineVirtual() const; // beforecxx20-error {{virtual function cannot be constexpr}}
43 // - its return type shall be a literal type;
44 // Once we support P2448R2 constexpr functions will be allowd to return non-literal types
45 // The destructor will also be allowed
46 constexpr NonLiteral NonLiteralReturn() const { return {}; } // beforecxx23-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
47 constexpr void VoidReturn() const { return; } // beforecxx14-error {{constexpr function's return type 'void' is not a literal type}}
48 constexpr ~T(); // beforecxx20-error {{destructor cannot be declared constexpr}}
50 typedef NonLiteral F() const;
51 constexpr F NonLiteralReturn2; // ok until definition
53 // - each of its parameter types shall be a literal type;
54 // Once we support P2448R2 constexpr functions will be allowd to have parameters of non-literal types
55 constexpr int NonLiteralParam(NonLiteral) const { return 0; } // beforecxx23-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
56 typedef int G(NonLiteral) const;
57 constexpr G NonLiteralParam2; // ok until definition
59 // - its function-body shall be = delete, = default,
60 constexpr int Deleted() const = delete;
61 // It's not possible for the function-body to legally be "= default" here
62 // (that is, for a non-constructor function) in C++11.
63 // Other than constructors, only the copy- and move-assignment operators and
64 // destructor can be defaulted. Destructors can't be constexpr since they
65 // don't have a literal return type. Defaulted assignment operators can't be
66 // constexpr since they can't be const.
67 constexpr T &operator=(const T &) = default; // beforecxx14-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}} \
68 // beforecxx14-warning {{C++14}} \
69 // cxx14_20-error{{defaulted definition of copy assignment operator cannot be marked constexpr}}
72 constexpr int T::OutOfLineVirtual() const { return 0; }
73 #if __cplusplus >= 201402L
74 struct T2 {
75 int n = 0;
76 constexpr T2 &operator=(const T2&) = default; // ok
78 struct T3 {
79 constexpr T3 &operator=(const T3 &) const = default; // beforecxx20-error {{an explicitly-defaulted copy assignment operator may not have 'const' or 'volatile' qualifiers}} \
80 // aftercxx20-warning {{explicitly defaulted copy assignment operator is implicitly deleted}} \
81 // aftercxx20-note {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
83 #endif
84 struct U {
85 constexpr U SelfReturn() const;
86 constexpr int SelfParam(U) const;
89 struct V : virtual U { // expected-note {{here}}
90 constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
93 // or a compound-statememt that contains only [CXX11]
94 constexpr int AllowedStmtsCXX11() {
95 // - null statements
98 // - static_assert-declarations
99 static_assert(true, "the impossible happened!");
101 // - typedef declarations and alias-declarations that do not define classes
102 // or enumerations
103 typedef int I;
104 typedef struct S T;
105 using J = int;
106 using K = int[sizeof(I) + sizeof(J)];
107 // Note, the standard requires we reject this.
108 struct U;
110 // - using-declarations
111 using N::C;
113 // - using-directives
114 using namespace N;
116 // - and exactly one return statement
117 return sizeof(K) + sizeof(C) + sizeof(K);
120 // or a compound-statement that does not contain [C++14]
121 constexpr int DisallowedStmtsCXX14_1(bool b) {
122 // - an asm-definition
123 if (b)
124 asm("int3"); // beforecxx20-warning {{use of this statement in a constexpr function is a C++20 extension}}
125 return 0;
127 constexpr int DisallowedStmtsCXX14_2() {
128 return 0; // beforecxx14-note {{previous}}
129 // - a goto statement
130 goto x; // beforecxx23-warning {{use of this statement in a constexpr function is a C++23 extension}}
132 return 0; // beforecxx14-warning {{multiple return}}
134 constexpr int DisallowedStmtsCXX14_2_1() {
135 merp: // beforecxx23-warning {{use of this statement in a constexpr function is a C++23 extension}}
136 return 0;
138 constexpr int DisallowedStmtsCXX14_3() {
139 // - a try-block,
140 try { } // beforecxx20-warning {{use of this statement in a constexpr function is a C++20 extension}}
141 catch (...) {}
142 return 0;
144 constexpr int DisallowedStmtsCXX14_4() {
145 // - a definition of a variable of non-literal type
146 return 0;
147 NonLiteral nl; // beforecxx23-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function before C++23}} \
148 // beforecxx23-note@14 {{'NonLiteral' is not literal}}
151 constexpr int DisallowedStmtsCXX14_5() {
152 return 0;
153 // - a definition of a variable of static storage duration
154 static constexpr int n = 123; // beforecxx23-warning {{definition of a static variable in a constexpr function is a C++23 extension}} \
155 // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
158 constexpr int DisallowedStmtsCXX14_6() {
159 // - a definition of a variable of thread storage duration
160 return 0;
161 thread_local constexpr int n = 123; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}} \
162 // beforecxx23-warning {{definition of a thread_local variable in a constexpr function is a C++23 extension}}
164 constexpr int DisallowedStmtsCXX14_7() {
165 // - a definition of a variable for which no initialization is performed
166 return 0;
167 int n; // beforecxx20-warning {{uninitialized variable in a constexpr function}}
170 constexpr int ForStmt() {
171 for (int n = 0; n < 10; ++n) {} // beforecxx14-error {{statement not allowed in constexpr function}}
172 return 0;
175 constexpr int VarDecl() {
176 int a = 0; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
177 return 0;
179 constexpr int ConstexprVarDecl() {
180 constexpr int a = 0; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
181 return 0;
183 constexpr int VarWithCtorDecl() {
184 Literal a; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
185 return 0;
188 NonLiteral nl;
189 constexpr NonLiteral &ExternNonLiteralVarDecl() {
190 extern NonLiteral nl; // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
191 return nl;
193 static_assert(&ExternNonLiteralVarDecl() == &nl, "");
195 constexpr int FuncDecl() {
196 constexpr int ForwardDecl(int); // beforecxx14-warning {{use of this statement in a constexpr function is a C++14 extension}}
197 return ForwardDecl(42);
200 constexpr int ClassDecl1() {
201 typedef struct {} S1; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}}
202 return 0;
205 constexpr int ClassDecl2() {
206 using S2 = struct {}; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}}
207 return 0;
210 constexpr int ClassDecl3() {
211 struct S3 {}; // beforecxx14-warning {{type definition in a constexpr function is a C++14 extension}}
212 return 0;
215 constexpr int NoReturn() {} // beforecxx23-error {{no return statement in constexpr function}}
216 constexpr int MultiReturn() {
217 return 0; // beforecxx14-note {{return statement}}
218 return 0; // beforecxx14-warning {{multiple return statements in constexpr function}}
221 // - every constructor call and implicit conversion used in initializing the
222 // return value shall be one of those allowed in a constant expression.
224 // We implement the proposed resolution of DR1364 and ignore this bullet.
225 // However, we implement the spirit of the check as part of the p5 checking that
226 // a constexpr function must be able to produce a constant expression.
227 namespace DR1364 {
228 constexpr int f(int k) {
229 return k; // ok, even though lvalue-to-rvalue conversion of a function
230 // parameter is not allowed in a constant expression.
232 int kGlobal; // beforecxx23-note {{here}}
233 constexpr int f() { // beforecxx23-error {{constexpr function never produces a constant expression}}
234 return kGlobal; // beforecxx23-note {{read of non-const}}
238 namespace rdar13584715 {
239 typedef __PTRDIFF_TYPE__ ptrdiff_t;
241 template<typename T> struct X {
242 static T value() {};
245 void foo(ptrdiff_t id) {
246 switch (id) {
247 case reinterpret_cast<ptrdiff_t>(&X<long>::value): // expected-error{{case value is not a constant expression}} \
248 // expected-note{{reinterpret_cast is not allowed in a constant expression}}
249 break;
254 namespace std_example {
255 constexpr int square(int x) {
256 return x * x;
258 constexpr long long_max() {
259 return 2147483647;
261 constexpr int abs(int x) {
262 if (x < 0) // beforecxx14-warning {{C++14}}
263 x = -x;
264 return x;
266 constexpr int first(int n) {
267 return 0;
268 static int value = n; // beforecxx23-warning {{definition of a static variable in a constexpr function is a C++23 extension}} \
269 // beforecxx14-warning {{variable declaration in a constexpr function is a C++14 extension}}
271 constexpr int uninit() {
272 int a; // beforecxx20-warning {{uninitialized}}
273 return a;
275 constexpr int prev(int x) { // beforecxx14-error {{never produces a constant expression}}
276 return --x; // beforecxx14-note {{subexpression}}
279 constexpr int g(int x, int n) {
280 int r = 1; // beforecxx14-warning{{C++14}}
281 while (--n > 0) // beforecxx14-error {{statement not allowed in constexpr function}}
282 r *= x;
283 return r;
287 struct Base {
288 constexpr Base() = default;
290 struct Derived : virtual Base { // expected-note 3{{virtual base class declared here}}
291 constexpr Derived() = default; // expected-error {{default constructor cannot be 'constexpr' in a class with virtual base class}}
292 constexpr Derived(const Derived&) = default; // expected-error {{copy constructor cannot be 'constexpr' in a class with virtual base class}}
293 constexpr Derived(Derived&&) = default; // expected-error {{move constructor cannot be 'constexpr' in a class with virtual base class}}