1 // RUN: %clang_cc1 -std=c++23 -verify -fsyntax-only %s 2 3 template <typename T, typename U> 4 constexpr bool is_same = false; 5 6 template <typename T> 7 constexpr bool is_same<T, T> = true; 8 9 void f() { 10 11 int y; 12 13 static_assert(is_same<const int &, 14 decltype([x = 1] -> decltype((x)) { return x; }())>); 15 16 static_assert(is_same<int &, 17 decltype([x = 1] mutable -> decltype((x)) { return x; }())>); 18 19 static_assert(is_same<const int &, 20 decltype([=] -> decltype((y)) { return y; }())>); 21 22 static_assert(is_same<int &, 23 decltype([=] mutable -> decltype((y)) { return y; }())>); 24 25 static_assert(is_same<const int &, 26 decltype([=] -> decltype((y)) { return y; }())>); 27 28 static_assert(is_same<int &, 29 decltype([=] mutable -> decltype((y)) { return y; }())>); 30 31 auto ref = [&x = y]( 32 decltype([&](decltype(x)) { return 0; }) y) { 33 return x; 34 }; 35 } 36 37 void test_noexcept() { 38 39 int y; 40 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))>) {}())); 49 } 50 51 template<typename T> 52 void test_requires() { 53 54 int x; 55 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 (); 76 77 [x = 1]() requires is_same<const int &, decltype((x))> {} (); 78 [x = 1]() mutable requires is_same<int &, decltype((x))> {} (); 79 } 80 81 void use() { 82 test_requires<int>(); 83 } 84 85 void err() { 86 int y, z; 87 (void)[x = 1]<typename T> 88 requires(is_same<const int &, decltype((x))>) {}; 89 90 (void)[x = 1]<typename T = decltype((x))>{}; 91 92 (void)[=]<typename T = decltype((y))>{}; 93 94 (void)[z]<typename T = decltype((z))>{}; 95 } 96 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"))){}(); 102 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()'}} 106 107 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"))){}(); 111 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()'}} 115 } 116 117 void nested() { 118 int x, y, z; 119 (void)[&]( 120 decltype([&]( 121 decltype([=]( 122 decltype([&]( 123 decltype([&](decltype(x)) {})) {})) {})) {})){}; 124 125 (void)[&]( 126 decltype([&]( 127 decltype([&]( 128 decltype([&]( 129 decltype([&](decltype(y)) {})) {})) {})) {})){}; 130 131 (void)[=]( 132 decltype([=]( 133 decltype([=]( 134 decltype([=]( 135 decltype([&]<decltype(z)> {})) {})) {})) {})){}; 136 } 137 138 template <typename T, typename U> 139 void dependent(U&& u) { 140 [&]() requires is_same<decltype(u), T> {}(); 141 } 142 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; 149 } 150 (); 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; 155 } 156 (); 157 } 158 159 template <typename T, typename...> 160 struct extract_type { 161 using type = T; 162 }; 163 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; 168 } 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; 172 } 173 (x...); 174 } 175 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); 185 } 186 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))>); 195 }; 196 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)>); 204 }; 205 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)>); 210 }; 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))>); 215 }; 216 } 217 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))>); 227 }; 228 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)>); 236 }; 237 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)>); 242 }; 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))>); 247 }; 248 } 249 250 namespace GH61267 { 251 template <typename> concept C = true; 252 253 template<typename> 254 void f(int) { 255 int i; 256 [i]<C P>(P) {}(0); 257 i = 4; 258 } 259 260 void test() { f<int>(0); } 261 262 } 263 264 namespace GH65067 { 265 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 {}; }; 271 } 272 }; 273 a<void> e; 274 auto fn1() { 275 e.c([](int) {}); 276 } 277 278 } 279 280 namespace GH63675 { 281 282 template <class _Tp> _Tp __declval(); 283 struct __get_tag { 284 template <class _Tag> void operator()(_Tag); 285 }; 286 template <class _ImplFn> struct __basic_sender { 287 using __tag_t = decltype(__declval<_ImplFn>()(__declval<__get_tag>())); 288 _ImplFn __impl_; 289 }; 290 auto __make_basic_sender = []<class... _Children>( 291 _Children... __children) { 292 return __basic_sender{[... __children = __children]<class _Fun>( 293 _Fun __fun) -> decltype(__fun(__children...)) {}}; 294 }; 295 void __trans_tmp_1() { 296 __make_basic_sender(__trans_tmp_1); 297 } 298 299 } 300 301 namespace GH115931 { 302 303 struct Range {}; 304 305 template <Range> 306 struct LengthPercentage {}; 307 308 void reflectSum() { 309 Range resultR; 310 [&] (auto) -> LengthPercentage<resultR> { 311 return {}; 312 }(0); 313 } 314 315 } // namespace GH115931 316 317 namespace GH47400 { 318 319 struct Foo {}; 320 321 template <int, Foo> struct Arr {}; 322 323 template <int> struct S {}; 324 325 constexpr void foo() { 326 constexpr Foo f; 327 [&]<int is>() { 328 [&](Arr<is, f>) {}({}); // f constitutes an ODR-use 329 }.template operator()<42>(); 330 331 constexpr int C = 1; 332 [] { 333 [](S<C>) { }({}); // ... while C doesn't 334 }(); 335 } 336 337 } // namespace GH47400 338 339 namespace GH84961 { 340 341 template <typename T> void g(const T &t) {} 342 343 template <typename T> void f(const T &t) { 344 [t] { g(t); }(); 345 } 346 347 void h() { 348 f(h); 349 } 350 351 } // namespace GH84961 352