352 lines · cpp
1// RUN: %clang_cc1 -std=c++23 -verify -fsyntax-only %s2 3template <typename T, typename U>4constexpr bool is_same = false;5 6template <typename T>7constexpr bool is_same<T, T> = true;8 9void 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 37void 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 51template<typename T>52void 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 81void use() {82 test_requires<int>();83}84 85void 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 97void 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 117void 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 138template <typename T, typename U>139void dependent(U&& u) {140 [&]() requires is_same<decltype(u), T> {}();141}142 143template <typename T>144void 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 159template <typename T, typename...>160struct extract_type {161 using type = T;162};163 164template <typename... T>165void 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 176void 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 187void 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 218template <typename T>219void 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 250namespace GH61267 {251template <typename> concept C = true;252 253template<typename>254void f(int) {255 int i;256 [i]<C P>(P) {}(0);257 i = 4;258}259 260void test() { f<int>(0); }261 262}263 264namespace GH65067 {265 266template <typename> class a {267public: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};273a<void> e;274auto fn1() {275 e.c([](int) {});276}277 278}279 280namespace GH63675 {281 282template <class _Tp> _Tp __declval();283struct __get_tag {284 template <class _Tag> void operator()(_Tag);285};286template <class _ImplFn> struct __basic_sender {287 using __tag_t = decltype(__declval<_ImplFn>()(__declval<__get_tag>()));288 _ImplFn __impl_;289};290auto __make_basic_sender = []<class... _Children>(291 _Children... __children) {292 return __basic_sender{[... __children = __children]<class _Fun>(293 _Fun __fun) -> decltype(__fun(__children...)) {}};294};295void __trans_tmp_1() {296 __make_basic_sender(__trans_tmp_1);297}298 299}300 301namespace GH115931 {302 303struct Range {};304 305template <Range>306struct LengthPercentage {};307 308void reflectSum() {309 Range resultR;310 [&] (auto) -> LengthPercentage<resultR> { 311 return {};312 }(0);313}314 315} // namespace GH115931316 317namespace GH47400 {318 319struct Foo {};320 321template <int, Foo> struct Arr {};322 323template <int> struct S {};324 325constexpr void foo() {326 constexpr Foo f;327 [&]<int is>() {328 [&](Arr<is, f>) {}({}); // f constitutes an ODR-use329 }.template operator()<42>();330 331 constexpr int C = 1;332 [] {333 [](S<C>) { }({}); // ... while C doesn't334 }();335}336 337} // namespace GH47400338 339namespace GH84961 {340 341template <typename T> void g(const T &t) {}342 343template <typename T> void f(const T &t) {344 [t] { g(t); }();345}346 347void h() {348 f(h);349}350 351} // namespace GH84961352