1 // RUN: %clang_cc1 -std=c++23 -verify -fsyntax-only %s
3 template <typename T
, typename U
>
4 constexpr bool is_same
= false;
7 constexpr bool is_same
<T
, T
> = true;
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
; }())>);
32 decltype([&](decltype(x
)) { return 0; }) y
) {
37 void test_noexcept() {
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
))>) {}()));
52 void test_requires() {
56 [x
= 1]() requires is_same
<const int &, decltype((x
))> {}
58 [x
= 1]() mutable requires is_same
<int &, decltype((x
))> {}
60 [x
]() requires is_same
<const int &, decltype((x
))> {}
62 [x
]() mutable requires is_same
<int &, decltype((x
))> {}
64 [=]() requires is_same
<const int &, decltype((x
))> {}
66 [=]() mutable requires is_same
<int &, decltype((x
))> {}
68 [&]() requires is_same
<int &, decltype((x
))> {}
70 [&]() mutable requires is_same
<int &, decltype((x
))> {}
72 [&x
]() requires is_same
<int &, decltype((x
))> {}
74 [&x
]() mutable requires is_same
<int &, decltype((x
))> {}
77 [x
= 1]() requires is_same
<const int &, decltype((x
))> {} ();
78 [x
= 1]() mutable requires is_same
<int &, decltype((x
))> {} ();
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() {
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()'}}
123 decltype([&](decltype(x
)) {})) {})) {})) {})){};
129 decltype([&](decltype(y
)) {})) {})) {})) {})){};
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 &>) {
151 [ y
= x
+ 1, x
]() -> decltype(y
+ x
)
152 requires(is_same
<decltype((y
)), const int &>
153 && is_same
<decltype((x
)), const int &>) {
159 template <typename T
, typename
...>
160 struct extract_type
{
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 &> && ...)) {
170 [... y
= x
, x
... ](auto...) -> typename extract_type
<decltype(y
)...>::type
requires((is_same
<decltype((y
)), const int &> && ...) && (is_same
<decltype((x
)), const int &> && ...)) {
176 void test_dependent() {
182 dependent
<const int&>(cr
);
183 dependent_init_capture(0);
184 dependent_variadic_capture(1, 2, 3, 4);
187 void check_params() {
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() {
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
))>);
251 template <typename
> concept C
= true;
260 void test() { f
<int>(0); }
266 template <typename
> class a
{
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 {}; };
282 template <class _Tp
> _Tp
__declval();
284 template <class _Tag
> void operator()(_Tag
);
286 template <class _ImplFn
> struct __basic_sender
{
287 using __tag_t
= decltype(__declval
<_ImplFn
>()(__declval
<__get_tag
>()));
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
);
305 template <int, Foo
> struct Arr
{};
307 template <int> struct S
{};
309 constexpr void foo() {
312 [&](Arr
<is
, f
>) {}({}); // f constitutes an ODR-use
313 }.template operator()<42>();
317 [](S
<C
>) { }({}); // ... while C doesn't
321 } // namespace GH47400