[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CXX / drs / cwg20xx.cpp
blobb2dc5a9865e382c93d1a169b30a8d03fac4855bd
1 // RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify=expected,cxx98 -fexceptions -fcxx-exceptions -pedantic-errors
2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,cxx11 -fexceptions -fcxx-exceptions -pedantic-errors
3 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
4 // RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14 -fexceptions -fcxx-exceptions -pedantic-errors
5 // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,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-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
7 // RUN: %clang_cc1 -std=c++2c -triple x86_64-unknown-unknown %s -verify=expected,since-cxx11,since-cxx14,since-cxx20 -fexceptions -fcxx-exceptions -pedantic-errors
9 #if __cplusplus == 199711L
10 #define static_assert(...) __extension__ _Static_assert(__VA_ARGS__)
11 // cxx98-error@-1 {{variadic macros are a C99 feature}}
12 #endif
14 namespace cwg2007 { // cwg2007: 3.4
15 template<typename T> struct A { typename T::error e; };
16 template<typename T> struct B { };
17 B<A<void> > b1;
18 B<A<void> > b2 = b1;
19 int a = b2[0];
20 // cxx98-error@-1 {{type 'B<A<void> >' does not provide a subscript operator}}
21 // since-cxx11-error@-2 {{type 'B<A<void>>' does not provide a subscript operator}}
22 int b = __builtin_addressof(b2)->foo;
23 // cxx98-error@-1 {{no member named 'foo' in 'cwg2007::B<cwg2007::A<void> >'}}
24 // since-cxx11-error@-2 {{no member named 'foo' in 'cwg2007::B<cwg2007::A<void>>'}}
27 // cwg2009: na
29 namespace cwg2026 { // cwg2026: 11
30 template<int> struct X {};
32 const int a = a + 1; // #cwg2026-a
33 // expected-warning@-1 {{variable 'a' is uninitialized when used within its own initialization}}
34 X<a> xa; // #cwg2026-xa
35 // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}}
36 // cxx98-note@-2 {{initializer of 'a' is not a constant expression}}
37 // cxx98-note@#cwg2026-a {{declared here}}
38 // since-cxx11-error@#cwg2026-xa {{non-type template argument is not a constant expression}}
39 // since-cxx11-note@#cwg2026-xa {{initializer of 'a' is not a constant expression}}
40 // since-cxx11-note@#cwg2026-a {{declared here}}
42 #if __cplusplus >= 201103L
43 constexpr int b = b;
44 // since-cxx11-error@-1 {{constexpr variable 'b' must be initialized by a constant expression}}
45 // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}}
46 [[clang::require_constant_initialization]] int c = c;
47 // since-cxx11-error@-1 {{variable does not have a constant initializer}}
48 // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}}
49 // cxx11-note@-3 {{read of non-const variable 'c' is not allowed in a constant expression}}
50 // cxx11-note@-4 {{declared here}}
51 // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}}
52 #endif
54 #if __cplusplus >= 202002L
55 constinit int d = d;
56 // since-cxx20-error@-1 {{variable does not have a constant initializer}}
57 // since-cxx20-note@-2 {{required by 'constinit' specifier here}}
58 // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}}
59 #endif
61 void f() {
62 static const int e = e + 1; // #cwg2026-e
63 // expected-warning@-1 {{static variable 'e' is suspiciously used within its own initialization}}
64 X<e> xe; // #cwg2026-xe
65 // cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}}
66 // cxx98-note@-2 {{initializer of 'e' is not a constant expression}}
67 // cxx98-note@#cwg2026-e {{declared here}}
68 // since-cxx11-error@#cwg2026-xe {{non-type template argument is not a constant expression}}
69 // since-cxx11-note@#cwg2026-xe {{initializer of 'e' is not a constant expression}}
70 // since-cxx11-note@#cwg2026-e {{declared here}}
72 #if __cplusplus >= 201103L
73 static constexpr int f = f;
74 // since-cxx11-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}}
75 // since-cxx11-note@-2 {{read of object outside its lifetime is not allowed in a constant expression}}
76 [[clang::require_constant_initialization]] static int g = g;
77 // since-cxx11-error@-1 {{variable does not have a constant initializer}}
78 // since-cxx11-note@-2 {{required by 'require_constant_initialization' attribute here}}
79 // cxx11-note@-3 {{read of non-const variable 'g' is not allowed in a constant expression}}
80 // cxx11-note@-4 {{declared here}}
81 // since-cxx14-note@-5 {{read of object outside its lifetime is not allowed in a constant expression}}
82 #endif
84 #if __cplusplus >= 202002L
85 static constinit int h = h;
86 // since-cxx20-error@-1 {{variable does not have a constant initializer}}
87 // since-cxx20-note@-2 {{required by 'constinit' specifier here}}
88 // since-cxx20-note@-3 {{read of object outside its lifetime is not allowed in a constant expression}}
89 #endif
93 namespace cwg2049 { // cwg2049: 18
94 #if __cplusplus >= 202302L
95 template <int* x = {}> struct X {};
96 X<> a;
97 X<nullptr> b;
98 static_assert(__is_same(decltype(a), decltype(b)));
99 #endif
102 namespace cwg2061 { // cwg2061: yes
103 #if __cplusplus >= 201103L
104 namespace A {
105 inline namespace b {
106 namespace C {
107 // 'f' is the example from the DR. 'S' is an example where if we didn't
108 // properly handle the two being the same, we would get an incomplete
109 // type error during attempted instantiation.
110 template<typename T> void f();
111 template<typename T> struct S;
116 namespace A {
117 namespace C {
118 template<> void f<int>() { }
119 template<> struct S<int> { };
123 void use() {
124 A::C::f<int>();
125 A::C::S<int> s;
127 #endif // C++11
130 namespace cwg2076 { // cwg2076: 13
131 #if __cplusplus >= 201103L
132 namespace std_example {
133 struct A { A(int); };
134 struct B { B(A); };
135 B b{{0}};
137 struct Params { int a; int b; };
138 struct Foo {
139 Foo(Params);
141 Foo foo{{1, 2}};
144 struct string_view {
145 string_view(int); // not an aggregate
147 struct string {
148 string(int); // not an aggregate
149 operator string_view() const;
152 void foo(const string &); // #cwg2076-foo
153 void bar(string_view); // #cwg2076-bar
155 void func(const string &arg) {
156 // An argument in one set of braces is subject to user-defined conversions;
157 // an argument in two sets of braces is not, but an identity conversion is
158 // still OK.
159 foo(arg);
160 foo({arg});
161 foo({{arg}});
162 foo({{{arg}}});
163 // since-cxx11-error@-1 {{no matching function}}
164 // since-cxx11-note@#cwg2076-foo {{cannot convert initializer list}}
165 bar(arg);
166 bar({arg});
167 bar({{arg}});
168 // since-cxx11-error@-1 {{no matching function}}
169 // since-cxx11-note@#cwg2076-bar {{cannot convert initializer list}}
170 bar({{{arg}}});
171 // since-cxx11-error@-1 {{no matching function}}
172 // since-cxx11-note@#cwg2076-bar {{cannot convert initializer list}}
174 #endif
177 namespace cwg2082 { // cwg2082: 11
178 void test1(int x, int = sizeof(x)); // ok
179 #if __cplusplus >= 201103L
180 void test2(int x, int = decltype(x){}); // ok
181 #endif
184 namespace cwg2083 { // cwg2083: partial
185 #if __cplusplus >= 201103L
186 void non_const_mem_ptr() {
187 struct A {
188 int x;
189 int y;
191 constexpr A a = {1, 2};
192 struct B {
193 int A::*p;
194 constexpr int g() const {
195 // OK, not an odr-use of 'a'.
196 return a.*p;
199 static_assert(B{&A::x}.g() == 1, "");
200 static_assert(B{&A::y}.g() == 2, "");
202 #endif
204 const int a = 1;
205 int b;
206 // Note, references only get special odr-use / constant initializxer
207 // treatment in C++11 onwards. We continue to apply that even after CWG2083.
208 void ref_to_non_const() {
209 int c;
210 const int &ra = a; // #cwg2083-ra
211 int &rb = b; // #cwg2083-rb
212 int &rc = c; // #cwg2083-rc
213 struct A {
214 int f() {
215 int a = ra;
216 // cxx98-error@-1 {{reference to local variable 'ra' declared in enclosing function 'cwg2083::ref_to_non_const'}}
217 // cxx98-note@#cwg2083-ra {{'ra' declared here}}
218 int b = rb;
219 // cxx98-error@-1 {{reference to local variable 'rb' declared in enclosing function 'cwg2083::ref_to_non_const'}}
220 // cxx98-note@#cwg2083-rb {{'rb' declared here}}
221 int c = rc;
222 // expected-error@-1 {{reference to local variable 'rc' declared in enclosing function 'cwg2083::ref_to_non_const'}}
223 // expected-note@#cwg2083-rc {{'rc' declared here}}
224 return a + b + c;
229 #if __cplusplus >= 201103L
230 struct NoMut1 { int a, b; };
231 struct NoMut2 { NoMut1 m; };
232 struct NoMut3 : NoMut1 {
233 constexpr NoMut3(int a, int b) : NoMut1{a, b} {}
235 struct Mut1 {
236 int a;
237 mutable int b;
239 struct Mut2 { Mut1 m; };
240 struct Mut3 : Mut1 {
241 constexpr Mut3(int a, int b) : Mut1{a, b} {}
243 void mutable_subobjects() {
244 constexpr NoMut1 nm1 = {1, 2};
245 constexpr NoMut2 nm2 = {1, 2};
246 constexpr NoMut3 nm3 = {1, 2};
247 constexpr Mut1 m1 = {1, 2}; // #cwg2083-m1
248 constexpr Mut2 m2 = {1, 2}; // #cwg2083-m2
249 constexpr Mut3 m3 = {1, 2}; // #cwg2083-m3
250 struct A {
251 void f() {
252 static_assert(nm1.a == 1, "");
253 static_assert(nm2.m.a == 1, "");
254 static_assert(nm3.a == 1, "");
255 // Can't even access a non-mutable member of a variable containing mutable fields.
256 static_assert(m1.a == 1, "");
257 // since-cxx11-error@-1 {{reference to local variable 'm1' declared in enclosing function 'cwg2083::mutable_subobjects'}}
258 // since-cxx11-note@#cwg2083-m1 {{'m1' declared here}}
259 static_assert(m2.m.a == 1, "");
260 // since-cxx11-error@-1 {{reference to local variable 'm2' declared in enclosing function 'cwg2083::mutable_subobjects'}}
261 // since-cxx11-note@#cwg2083-m2 {{'m2' declared here}}
262 static_assert(m3.a == 1, "");
263 // since-cxx11-error@-1 {{reference to local variable 'm3' declared in enclosing function 'cwg2083::mutable_subobjects'}}
264 // since-cxx11-note@#cwg2083-m3 {{'m3' declared here}}
268 #endif
270 void ellipsis() {
271 void ellipsis(...);
272 struct A {};
273 const int n = 0;
274 #if __cplusplus >= 201103L
275 constexpr
276 #endif
277 A a = {}; // #cwg2083-a
278 struct B {
279 void f() {
280 ellipsis(n);
281 // Even though this is technically modelled as an lvalue-to-rvalue
282 // conversion, it calls a constructor and binds 'a' to a reference, so
283 // it results in an odr-use.
284 ellipsis(a);
285 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::ellipsis'}}
286 // expected-note@#cwg2083-a {{'a' declared here}}
291 #if __cplusplus >= 201103L
292 void volatile_lval() {
293 struct A { int n; };
294 constexpr A a = {0}; // #cwg2083-a2
295 struct B {
296 void f() {
297 // An lvalue-to-rvalue conversion of a volatile lvalue always results
298 // in odr-use.
299 int A::*p = &A::n;
300 int x = a.*p;
301 volatile int A::*q = p;
302 int y = a.*q;
303 // since-cxx11-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::volatile_lval'}}
304 // since-cxx11-note@#cwg2083-a2 {{'a' declared here}}
308 #endif
310 void discarded_lval() {
311 struct A { int x; mutable int y; volatile int z; };
312 A a; // #cwg2083-a-3
313 int &r = a.x; // #cwg2083-r
314 struct B {
315 void f() {
316 // FIXME: We emit more errors than we should be. They are explicitly
317 // marked below.
318 a.x;
319 // expected-warning@-1 {{expression result unused}}
320 // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME
321 // expected-note@#cwg2083-a-3 {{'a' declared here}}
322 a.*&A::x;
323 // expected-warning@-1 {{expression result unused}}
324 // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME
325 // expected-note@#cwg2083-a-3 {{'a' declared here}}
326 true ? a.x : a.y; // #cwg2083-ternary
327 // expected-warning@-1 {{expression result unused}}
328 // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME
329 // expected-note@#cwg2083-a-3 {{'a' declared here}}
330 // expected-error@#cwg2083-ternary {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME
331 // expected-note@#cwg2083-a-3 {{'a' declared here}}
332 (void)a.x;
333 // expected-error@-1 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME
334 // expected-note@#cwg2083-a-3 {{'a' declared here}}
335 a.x, discarded_lval();
336 // expected-warning@-1 {{left operand of comma operator has no effect}}
337 // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}} FIXME
338 // expected-note@#cwg2083-a-3 {{'a' declared here}}
340 // 'volatile' qualifier triggers an lvalue-to-rvalue conversion.
341 a.z;
342 // cxx98-warning@-1 {{expression result unused; assign into a variable to force a volatile load}}
343 // expected-error@-2 {{reference to local variable 'a' declared in enclosing function 'cwg2083::discarded_lval'}}
344 // expected-note@#cwg2083-a-3 {{'a' declared here}}
346 // References always get "loaded" to determine what they reference,
347 // even if the result is discarded.
349 // expected-warning@-1 {{expression result unused}}
350 // expected-error@-2 {{reference to local variable 'r' declared in enclosing function 'cwg2083::discarded_lval'}}
351 // expected-note@#cwg2083-r {{'r' declared here}}
356 namespace dr_example_1 {
357 extern int globx;
358 int main() {
359 const int &x = globx; // #cwg2083-x
360 struct A {
361 const int *foo() { return &x; }
362 // cxx98-error@-1 {{reference to local variable 'x' declared in enclosing function 'cwg2083::dr_example_1::main'}}
363 // cxx98-note@#cwg2083-x {{'x' declared here}}
364 } a;
365 return *a.foo();
369 #if __cplusplus >= 201103L
370 namespace dr_example_2 {
371 struct A {
372 int q;
373 constexpr A(int q) : q(q) {}
374 constexpr A(const A &a) : q(a.q * 2) {} // (note, not called)
377 int main(void) {
378 constexpr A a(42);
379 constexpr int aq = a.q;
380 struct Q {
381 int foo() { return a.q; }
382 } q;
383 return q.foo();
386 // Checking odr-use does not invent an lvalue-to-rvalue conversion (and
387 // hence copy construction) on the potential result variable.
388 struct B {
389 int b = 42;
390 constexpr B() {}
391 constexpr B(const B&) = delete;
393 void f() {
394 constexpr B b;
395 struct Q {
396 constexpr int foo() const { return b.b; }
398 static_assert(Q().foo() == 42, "");
401 #endif
404 namespace cwg2091 { // cwg2091: 10
405 template<int &> struct X;
406 template<int &N> void f(X<N>&);
407 int n;
408 void g(X<n> &x) { f(x); }
410 namespace GH42233 {
411 enum E { I };
413 class AA { };
414 E EV[1] = {I};
416 template<class ENUM, const ENUM* const VALUES>
417 struct S
419 template< class E, const E* const V>
420 friend AA& operator<<( AA& os, const S<E,V>& e );
423 int f()
425 S< E, EV > x;
427 AA a;
428 a << x;
429 return 0;
431 } // namespace GH42233
432 } // namespace cwg2091
434 namespace cwg2094 { // cwg2094: 5
435 struct A { int n; };
436 struct B { volatile int n; };
437 static_assert(__is_trivially_copyable(volatile int), "");
438 static_assert(__is_trivially_copyable(const volatile int), "");
439 static_assert(__is_trivially_copyable(const volatile int[]), "");
440 static_assert(__is_trivially_copyable(A), "");
441 static_assert(__is_trivially_copyable(volatile A), "");
442 static_assert(__is_trivially_copyable(const volatile A), "");
443 static_assert(__is_trivially_copyable(const volatile A[]), "");
444 static_assert(__is_trivially_copyable(B), "");
446 static_assert(__is_trivially_constructible(A, A const&), "");
447 static_assert(__is_trivially_constructible(B, B const&), "");
449 static_assert(__is_trivially_assignable(A, const A&), "");
450 static_assert(__is_trivially_assignable(B, const B&), "");
453 // cwg2096: dup 2598