[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / lambda-capture-type-deduction.cpp
bloba86f30189899271f8e84b03713b27442e9104871
1 // RUN: %clang_cc1 -std=c++23 -verify -fsyntax-only %s
3 template <typename T, typename U>
4 constexpr bool is_same = false;
6 template <typename T>
7 constexpr bool is_same<T, T> = true;
9 void f() {
11 int y;
13 static_assert(is_same<const int &,
14 decltype([x = 1] -> decltype((x)) { return x; }())>);
16 static_assert(is_same<int &,
17 decltype([x = 1] mutable -> decltype((x)) { return x; }())>);
19 static_assert(is_same<const int &,
20 decltype([=] -> decltype((y)) { return y; }())>);
22 static_assert(is_same<int &,
23 decltype([=] mutable -> decltype((y)) { return y; }())>);
25 static_assert(is_same<const int &,
26 decltype([=] -> decltype((y)) { return y; }())>);
28 static_assert(is_same<int &,
29 decltype([=] mutable -> decltype((y)) { return y; }())>);
31 auto ref = [&x = y](
32 decltype([&](decltype(x)) { return 0; }) y) {
33 return x;
37 void test_noexcept() {
39 int y;
41 static_assert(noexcept([x = 1] noexcept(is_same<const int &, decltype((x))>) {}()));
42 static_assert(noexcept([x = 1] mutable noexcept(is_same<int &, decltype((x))>) {}()));
43 static_assert(noexcept([y] noexcept(is_same<const int &, decltype((y))>) {}()));
44 static_assert(noexcept([y] mutable noexcept(is_same<int &, decltype((y))>) {}()));
45 static_assert(noexcept([=] noexcept(is_same<const int &, decltype((y))>) {}()));
46 static_assert(noexcept([=] mutable noexcept(is_same<int &, decltype((y))>) {}()));
47 static_assert(noexcept([&] noexcept(is_same<int &, decltype((y))>) {}()));
48 static_assert(noexcept([&] mutable noexcept(is_same<int &, decltype((y))>) {}()));
51 template<typename T>
52 void test_requires() {
54 int x;
56 [x = 1]() requires is_same<const int &, decltype((x))> {}
57 ();
58 [x = 1]() mutable requires is_same<int &, decltype((x))> {}
59 ();
60 [x]() requires is_same<const int &, decltype((x))> {}
61 ();
62 [x]() mutable requires is_same<int &, decltype((x))> {}
63 ();
64 [=]() requires is_same<const int &, decltype((x))> {}
65 ();
66 [=]() mutable requires is_same<int &, decltype((x))> {}
67 ();
68 [&]() requires is_same<int &, decltype((x))> {}
69 ();
70 [&]() mutable requires is_same<int &, decltype((x))> {}
71 ();
72 [&x]() requires is_same<int &, decltype((x))> {}
73 ();
74 [&x]() mutable requires is_same<int &, decltype((x))> {}
75 ();
77 [x = 1]() requires is_same<const int &, decltype((x))> {} ();
78 [x = 1]() mutable requires is_same<int &, decltype((x))> {} ();
81 void use() {
82 test_requires<int>();
85 void err() {
86 int y, z;
87 (void)[x = 1]<typename T>
88 requires(is_same<const int &, decltype((x))>) {};
90 (void)[x = 1]<typename T = decltype((x))>{};
92 (void)[=]<typename T = decltype((y))>{};
94 (void)[z]<typename T = decltype((z))>{};
97 void gnu_attributes() {
98 int y;
99 (void)[=]() __attribute__((diagnose_if(!is_same<decltype((y)), const int &>, "wrong type", "warning"))){}();
100 // expected-warning@-1 {{wrong type}} expected-note@-1{{'diagnose_if' attribute on 'operator()'}}
101 (void)[=]() __attribute__((diagnose_if(!is_same<decltype((y)), int &>, "wrong type", "warning"))){}();
103 (void)[=]() __attribute__((diagnose_if(!is_same<decltype((y)), int &>, "wrong type", "warning"))) mutable {}();
104 (void)[=]() __attribute__((diagnose_if(!is_same<decltype((y)), const int &>, "wrong type", "warning"))) mutable {}();
105 // expected-warning@-1 {{wrong type}} expected-note@-1{{'diagnose_if' attribute on 'operator()'}}
108 (void)[x=1]() __attribute__((diagnose_if(!is_same<decltype((x)), const int &>, "wrong type", "warning"))){}();
109 // expected-warning@-1 {{wrong type}} expected-note@-1{{'diagnose_if' attribute on 'operator()'}}
110 (void)[x=1]() __attribute__((diagnose_if(!is_same<decltype((x)), int &>, "wrong type", "warning"))){}();
112 (void)[x=1]() __attribute__((diagnose_if(!is_same<decltype((x)), int &>, "wrong type", "warning"))) mutable {}();
113 (void)[x=1]() __attribute__((diagnose_if(!is_same<decltype((x)), const int &>, "wrong type", "warning"))) mutable {}();
114 // expected-warning@-1 {{wrong type}} expected-note@-1{{'diagnose_if' attribute on 'operator()'}}
117 void nested() {
118 int x, y, z;
119 (void)[&](
120 decltype([&](
121 decltype([=](
122 decltype([&](
123 decltype([&](decltype(x)) {})) {})) {})) {})){};
125 (void)[&](
126 decltype([&](
127 decltype([&](
128 decltype([&](
129 decltype([&](decltype(y)) {})) {})) {})) {})){};
131 (void)[=](
132 decltype([=](
133 decltype([=](
134 decltype([=](
135 decltype([&]<decltype(z)> {})) {})) {})) {})){};
138 template <typename T, typename U>
139 void dependent(U&& u) {
140 [&]() requires is_same<decltype(u), T> {}();
143 template <typename T>
144 void dependent_init_capture(T x = 0) {
145 [ y = x + 1, x ]() mutable -> decltype(y + x)
146 requires(is_same<decltype((y)), int &>
147 && is_same<decltype((x)), int &>) {
148 return y;
151 [ y = x + 1, x ]() -> decltype(y + x)
152 requires(is_same<decltype((y)), const int &>
153 && is_same<decltype((x)), const int &>) {
154 return y;
159 template <typename T, typename...>
160 struct extract_type {
161 using type = T;
164 template <typename... T>
165 void dependent_variadic_capture(T... x) {
166 [... y = x, x... ](auto...) mutable -> typename extract_type<decltype(y)...>::type requires((is_same<decltype((y)), int &> && ...) && (is_same<decltype((x)), int &> && ...)) {
167 return 0;
169 (x...);
170 [... y = x, x... ](auto...) -> typename extract_type<decltype(y)...>::type requires((is_same<decltype((y)), const int &> && ...) && (is_same<decltype((x)), const int &> && ...)) {
171 return 0;
173 (x...);
176 void test_dependent() {
177 int v = 0;
178 int & r = v;
179 const int & cr = v;
180 dependent<int&>(v);
181 dependent<int&>(r);
182 dependent<const int&>(cr);
183 dependent_init_capture(0);
184 dependent_variadic_capture(1, 2, 3, 4);
187 void check_params() {
188 int i = 0;
189 int &j = i;
190 (void)[=](decltype((j)) jp, decltype((i)) ip) {
191 static_assert(is_same<const int&, decltype((j))>);
192 static_assert(is_same<const int &, decltype((i))>);
193 static_assert(is_same<int &, decltype((jp))>);
194 static_assert(is_same<int &, decltype((ip))>);
197 (void)[=](decltype((j)) jp, decltype((i)) ip) mutable {
198 static_assert(is_same<int &, decltype((j))>);
199 static_assert(is_same<int &, decltype((i))>);
200 static_assert(is_same<int &, decltype((jp))>);
201 static_assert(is_same<int &, decltype((ip))>);
202 static_assert(is_same<int &, decltype(jp)>);
203 static_assert(is_same<int &, decltype(ip)>);
206 (void)[a = 0](decltype((a)) ap) mutable {
207 static_assert(is_same<int &, decltype((a))>);
208 static_assert(is_same<int, decltype(a)>);
209 static_assert(is_same<int &, decltype(ap)>);
211 (void)[a = 0](decltype((a)) ap) {
212 static_assert(is_same<const int &, decltype((a))>);
213 static_assert(is_same<int, decltype(a)>);
214 static_assert(is_same<int&, decltype((ap))>);
218 template <typename T>
219 void check_params_tpl() {
220 T i = 0;
221 T &j = i;
222 (void)[=](decltype((j)) jp, decltype((i)) ip) {
223 static_assert(is_same<const int&, decltype((j))>);
224 static_assert(is_same<const int &, decltype((i))>);
225 static_assert(is_same<const int &, decltype((jp))>);
226 static_assert(is_same<const int &, decltype((ip))>);
229 (void)[=](decltype((j)) jp, decltype((i)) ip) mutable {
230 static_assert(is_same<int &, decltype((j))>);
231 static_assert(is_same<int &, decltype((i))>);
232 static_assert(is_same<int &, decltype((jp))>);
233 static_assert(is_same<int &, decltype((ip))>);
234 static_assert(is_same<int &, decltype(jp)>);
235 static_assert(is_same<int &, decltype(ip)>);
238 (void)[a = 0](decltype((a)) ap) mutable {
239 static_assert(is_same<int &, decltype((a))>);
240 static_assert(is_same<int, decltype(a)>);
241 static_assert(is_same<int &, decltype(ap)>);
243 (void)[a = 0](decltype((a)) ap) {
244 static_assert(is_same<const int &, decltype((a))>);
245 static_assert(is_same<int, decltype(a)>);
246 static_assert(is_same<int&, decltype((ap))>);
250 namespace GH61267 {
251 template <typename> concept C = true;
253 template<typename>
254 void f(int) {
255 int i;
256 [i]<C P>(P) {}(0);
257 i = 4;
260 void test() { f<int>(0); }
264 namespace GH65067 {
266 template <typename> class a {
267 public:
268 template <typename b> void c(b f) { d<int>(f)(0); }
269 template <typename, typename b> auto d(b f) {
270 return [f = f](auto arg) -> a<decltype(f(arg))> { return {}; };
273 a<void> e;
274 auto fn1() {
275 e.c([](int) {});
280 namespace GH63675 {
282 template <class _Tp> _Tp __declval();
283 struct __get_tag {
284 template <class _Tag> void operator()(_Tag);
286 template <class _ImplFn> struct __basic_sender {
287 using __tag_t = decltype(__declval<_ImplFn>()(__declval<__get_tag>()));
288 _ImplFn __impl_;
290 auto __make_basic_sender = []<class... _Children>(
291 _Children... __children) {
292 return __basic_sender{[... __children = __children]<class _Fun>(
293 _Fun __fun) -> decltype(__fun(__children...)) {}};
295 void __trans_tmp_1() {
296 __make_basic_sender(__trans_tmp_1);
301 namespace GH47400 {
303 struct Foo {};
305 template <int, Foo> struct Arr {};
307 template <int> struct S {};
309 constexpr void foo() {
310 constexpr Foo f;
311 [&]<int is>() {
312 [&](Arr<is, f>) {}({}); // f constitutes an ODR-use
313 }.template operator()<42>();
315 constexpr int C = 1;
316 [] {
317 [](S<C>) { }({}); // ... while C doesn't
318 }();
321 } // namespace GH47400