[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CXX / drs / cwg25xx.cpp
blob87a728088ee6e4fcf4e18d0d231f59b5011970b9
1 // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected -fexceptions -fcxx-exceptions -pedantic-errors
2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
3 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,cxx11-14,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
4 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
5 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
6 // RUN: %clang_cc1 -std=c++23 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors
7 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx20,since-cxx23 -fexceptions -fcxx-exceptions -pedantic-errors
9 namespace std {
10 struct type_info{};
11 } // namespace std
13 // cwg2504 is in cwg2504.cpp
15 namespace cwg2512 { // cwg2512: 2.7
16 struct A; // #cwg2512-A
17 void foo(A* p) {
18 typeid(*p);
19 // expected-error@-1 {{'typeid' of incomplete type 'A'}}
20 // expected-note@#cwg2512-A {{forward declaration of 'cwg2512::A'}}
22 } // namespace cwg2512
24 namespace cwg2516 { // cwg2516: 3.0
25 // NB: reusing 1482 test
26 #if __cplusplus >= 201103L
27 template <typename T> struct S {
28 typedef char I;
30 enum E2 : S<E2>::I { e };
31 // since-cxx11-error@-1 {{use of undeclared identifier 'E2'}}
32 #endif
33 } // namespace cwg2516
35 namespace cwg2518 { // cwg2518: 17
37 #if __cplusplus >= 201103L
38 template <class T>
39 void f(T t) {
40 if constexpr (sizeof(T) != sizeof(int)) {
41 // cxx11-14-error@-1 {{constexpr if is a C++17 extension}}
42 static_assert(false, "must be int-sized");
43 // since-cxx11-error@-1 {{static assertion failed: must be int-sized}}
44 // since-cxx11-note@#cwg2518-f-c {{in instantiation of function template specialization 'cwg2518::f<char>' requested here}}
48 void g(char c) {
49 f(0);
50 f(c); // #cwg2518-f-c
53 template <typename Ty>
54 struct S {
55 static_assert(false);
56 // cxx11-14-error@-1 {{'static_assert' with no message is a C++17 extension}}
57 // since-cxx11-error@-2 {{static assertion failed}}
58 // since-cxx11-note@#cwg2518-S-double {{in instantiation of template class 'cwg2518::S<double>' requested here}}
61 template <>
62 struct S<int> {};
64 template <>
65 struct S<float> {};
67 int test_specialization() {
68 S<int> s1;
69 S<float> s2;
70 S<double> s3; // #cwg2518-S-double
72 #endif
76 namespace cwg2521 { // cwg2521: 17
77 #if __cplusplus >= 201103L
78 #pragma clang diagnostic push
79 #pragma clang diagnostic warning "-Wdeprecated-literal-operator"
80 long double operator"" _\u03C0___(long double);
81 // since-cxx11-warning@-1 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
82 // since-cxx11-warning@-2 {{user-defined literal suffixes containing '__' are reserved}}
84 template <char... Chars> decltype(sizeof 0)
85 operator"" _div();
86 // since-cxx11-warning@-1 {{identifier '_div' preceded by whitespace in a literal operator declaration is deprecated}}
88 using ::cwg2521::operator"" _\u03C0___;
89 using ::cwg2521::operator""_div;
90 // since-cxx11-warning@-2 {{identifier '_π___' preceded by whitespace in a literal operator declaration is deprecated}}
92 long double operator"" _RESERVED(long double);
93 // since-cxx11-warning@-1 {{identifier '_RESERVED' preceded by whitespace in a literal operator declaration is deprecated}}
94 #pragma clang diagnostic pop
95 #endif
96 } // namespace cwg2521
98 namespace cwg2547 { // cwg2547: 20
99 #if __cplusplus >= 202302L
100 struct S;
101 // since-cxx23-note@-1 {{forward declaration of 'cwg2547::S'}}
102 // since-cxx23-note@-2 {{forward declaration of 'cwg2547::S'}}
103 // since-cxx23-note@-3 {{forward declaration of 'cwg2547::S'}}
104 bool operator==(S, S) = default; // error: S is not complete
105 // since-cxx23-error@-1 {{variable has incomplete type 'S'}}
106 // since-cxx23-error@-2 {{variable has incomplete type 'S'}}
107 // since-cxx23-error@-3 {{equality comparison operator is not a friend of incomplete class 'cwg2547::S'}}
108 struct S {
109 friend bool operator==(S, const S&) = default; // error: parameters of different types
110 // since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'S' vs 'const S &')}}
112 enum E { };
113 bool operator==(E, E) = default; // error: not a member or friend of a class
114 // since-cxx23-error@-1 {{invalid parameter type for non-member defaulted equality comparison operator; found 'E', expected class or reference to a constant class}}
116 struct S2 {
117 bool operator==(this int, S2) = default;
118 // since-cxx23-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'int', expected 'const cwg2547::S2 &'}}
120 #endif
121 } // namespace cwg2547
123 #if __cplusplus >= 202302L
124 namespace cwg2553 { // cwg2553: 18 review 2023-07-14
125 struct B {
126 virtual void f(this B&);
127 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}}
128 static void f(this B&);
129 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a static function}}
130 virtual void g(); // #cwg2553-g
132 struct D : B {
133 void g(this D&);
134 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}}
135 // since-cxx23-note@#cwg2553-g {{overridden virtual function is here}}
139 #endif
141 #if __cplusplus >= 202302L
142 namespace cwg2554 { // cwg2554: 18 review 2021-12-10
143 struct B {
144 virtual void f(); // #cwg2554-g
147 struct D : B {
148 void f(this D&);
149 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}}
150 // since-cxx23-note@#cwg2554-g {{overridden virtual function is here}}
153 struct D2 : B {
154 void f(this B&);
155 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}}
156 // since-cxx23-note@#cwg2554-g {{overridden virtual function is here}}
158 struct T {};
159 struct D3 : B {
160 void f(this T&);
161 // since-cxx23-error@-1 {{an explicit object parameter cannot appear in a virtual function}}
162 // since-cxx23-note@#cwg2554-g {{overridden virtual function is here}}
166 #endif
168 #if __cplusplus >= 202302L
169 namespace cwg2561 { // cwg2561: no
170 struct C {
171 constexpr C(auto) { }
173 void foo() {
174 constexpr auto b = [](this C) { return 1; };
175 // FIXME: closure type shouldn't have a conversion function to function
176 // pointer, because explicit object parameter is present.
177 constexpr int (*fp)(C) = b;
178 static_assert(fp(1) == 1);
179 static_assert((&decltype(b)::operator())(1) == 1);
183 #endif
186 namespace cwg2565 { // cwg2565: 16 open 2023-06-07
187 #if __cplusplus >= 202002L
188 template<typename T>
189 concept C = requires (typename T::type x) {
190 x + 1;
192 static_assert(!C<int>);
194 // Variant of this as reported in GH57487.
195 template<bool B> struct bool_constant
196 { static constexpr bool value = B; };
198 template<typename T>
199 using is_referenceable
200 = bool_constant<requires (T&) { true; }>;
202 static_assert(!is_referenceable<void>::value);
203 static_assert(is_referenceable<int>::value);
205 template<typename T, typename U>
206 concept TwoParams = requires (T *a, U b){ true;}; // #cwg2565-TPC
208 template<typename T, typename U>
209 requires TwoParams<T, U> // #cwg2565-TPSREQ
210 struct TwoParamsStruct{};
212 using TPSU = TwoParamsStruct<void, void>;
213 // since-cxx20-error@-1 {{constraints not satisfied for class template 'TwoParamsStruct'}}
214 // since-cxx20-note@#cwg2565-TPSREQ {{because 'TwoParams<void, void>' evaluated to false}}
215 // since-cxx20-note@#cwg2565-TPC {{because 'b' would be invalid: argument may not have 'void' type}}
217 template<typename T, typename ...U>
218 concept Variadic = requires (U* ... a, T b){ true;}; // #cwg2565-VC
220 template<typename T, typename ...U>
221 requires Variadic<T, U...> // #cwg2565-VSREQ
222 struct VariadicStruct{};
224 using VSU = VariadicStruct<void, int, char, double>;
225 // since-cxx20-error@-1 {{constraints not satisfied for class template 'VariadicStruct'}}
226 // since-cxx20-note@#cwg2565-VSREQ {{because 'Variadic<void, int, char, double>' evaluated to false}}
227 // since-cxx20-note@#cwg2565-VC {{because 'b' would be invalid: argument may not have 'void' type}}
229 template<typename T>
230 concept ErrorRequires = requires (ErrorRequires auto x) {
231 // since-cxx20-error@-1 {{a concept definition cannot refer to itself}} \
232 // since-cxx20-error@-1 {{'auto' not allowed in requires expression parameter}} \
233 // since-cxx20-note@-1 {{declared here}}
236 static_assert(ErrorRequires<int>);
237 // since-cxx20-error@-1 {{static assertion failed}}
238 // since-cxx20-note@-2 {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
240 template<typename T>
241 concept NestedErrorInRequires = requires (T x) { //
242 // since-cxx20-note@-1 {{declared here}}
243 requires requires (NestedErrorInRequires auto y) {
244 // since-cxx20-error@-1 {{a concept definition cannot refer to itself}} \
245 // since-cxx20-error@-1 {{'auto' not allowed in requires expression parameter}}
249 static_assert(NestedErrorInRequires<int>);
250 // expected-error@-1 {{static assertion failed}}
251 // expected-note@-2 {{because substituted constraint expression is ill-formed: constraint depends on a previously diagnosed expression}}
253 #endif
256 namespace cwg2583 { // cwg2583: 19
257 #if __cplusplus >= 201103L
258 struct A {
259 int i;
260 char c;
263 struct B {
264 int i;
265 alignas(8) char c;
268 union U {
269 A a;
270 B b;
273 union V {
274 A a;
275 alignas(64) B b;
278 static_assert(!__is_layout_compatible(A, B), "");
279 static_assert(__is_layout_compatible(U, V), "");
280 #endif
281 } // namespace cwg2583
283 namespace cwg2586 { // cwg2586: 20
284 #if __cplusplus >= 202302L
285 struct X {
286 X& operator=(this X&, const X&) = default;
287 X& operator=(this X&, X&) = default;
288 X& operator=(this X&&, X&&) = default;
289 // FIXME: The notes could be clearer on *how* the type differs
290 // e.g., "if an explicit object parameter is used it must be of type reference to 'X'"
291 X& operator=(this int, const X&) = default;
292 // since-cxx23-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
293 // since-cxx23-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
294 X& operator=(this X, const X&) = default;
295 // since-cxx23-warning@-1 {{explicitly defaulted copy assignment operator is implicitly deleted}}
296 // since-cxx23-note@-2 {{function is implicitly deleted because its declared type does not match the type of an implicit copy assignment operator}}
298 struct Y {
299 void operator=(this int, const Y&); // This is copy constructor, suppresses implicit declaration
301 static_assert([]<typename T = Y>{
302 return !requires(T t, const T& ct) { t = ct; };
303 }());
305 struct Z {
306 bool operator==(this const Z&, const Z&) = default;
307 bool operator==(this Z, Z) = default;
308 bool operator==(this Z, const Z&) = default;
309 // since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'Z' vs 'const Z &')}}
310 bool operator==(this const Z&, Z) = default;
311 // since-cxx23-error@-1 {{parameters for defaulted equality comparison operator must have the same type (found 'const Z &' vs 'Z')}}
312 bool operator==(this int, Z) = default;
313 // since-cxx23-error@-1 {{invalid parameter type for defaulted equality comparison operator; found 'int', expected 'const cwg2586::Z &'}}
315 #endif
316 } // namespace cwg2586
318 namespace cwg2598 { // cwg2598: 18
319 #if __cplusplus >= 201103L
320 struct NonLiteral {
321 NonLiteral();
324 struct anonymous1 {
325 union {} a;
327 static_assert(__is_literal(anonymous1), "");
329 struct anonymous2 {
330 union { char c; };
332 static_assert(__is_literal(anonymous2), "");
334 struct anonymous3 {
335 union { char c; NonLiteral NL; };
337 static_assert(__is_literal(anonymous3), "");
339 struct anonymous4 {
340 union { NonLiteral NL; };
342 static_assert(!__is_literal(anonymous4), "");
344 union empty {};
345 static_assert(__is_literal(empty), "");
347 union union1 { char c; };
348 static_assert(__is_literal(union1), "");
350 union union2 { char c; NonLiteral NL;};
351 static_assert(__is_literal(union2), "");
353 union union3 { NonLiteral NL;};
354 static_assert(!__is_literal(union3), "");
356 union union4 { union4(); };
357 static_assert(!__is_literal(union4), "");
359 union union5 { static NonLiteral NL; };
360 static_assert(__is_literal(union5), "");
362 struct Literal { constexpr Literal() {} };
363 union union6 { NonLiteral NL; Literal L; };
364 static_assert(__is_literal(union6), "");
366 #if __cplusplus >= 202003L
367 struct A { A(); };
368 union U {
369 A a;
370 constexpr U() {}
371 constexpr ~U() {}
373 static_assert(!__is_literal(U), "");
374 #endif
378 #endif