// RUN: %clang_cc1 -std=c++23 -verify -fsyntax-only %s template constexpr bool is_same = false; template constexpr bool is_same = true; void f() { int y; static_assert(is_same decltype((x)) { return x; }())>); static_assert(is_same decltype((x)) { return x; }())>); static_assert(is_same decltype((y)) { return y; }())>); static_assert(is_same decltype((y)) { return y; }())>); static_assert(is_same decltype((y)) { return y; }())>); static_assert(is_same decltype((y)) { return y; }())>); auto ref = [&x = y]( decltype([&](decltype(x)) { return 0; }) y) { return x; }; } void test_noexcept() { int y; static_assert(noexcept([x = 1] noexcept(is_same) {}())); static_assert(noexcept([x = 1] mutable noexcept(is_same) {}())); static_assert(noexcept([y] noexcept(is_same) {}())); static_assert(noexcept([y] mutable noexcept(is_same) {}())); static_assert(noexcept([=] noexcept(is_same) {}())); static_assert(noexcept([=] mutable noexcept(is_same) {}())); static_assert(noexcept([&] noexcept(is_same) {}())); static_assert(noexcept([&] mutable noexcept(is_same) {}())); } template void test_requires() { int x; [x = 1]() requires is_same {} (); [x = 1]() mutable requires is_same {} (); [x]() requires is_same {} (); [x]() mutable requires is_same {} (); [=]() requires is_same {} (); [=]() mutable requires is_same {} (); [&]() requires is_same {} (); [&]() mutable requires is_same {} (); [&x]() requires is_same {} (); [&x]() mutable requires is_same {} (); [x = 1]() requires is_same {} (); [x = 1]() mutable requires is_same {} (); } void use() { test_requires(); } void err() { int y, z; (void)[x = 1] requires(is_same) {}; (void)[x = 1]{}; (void)[=]{}; (void)[z]{}; } void gnu_attributes() { int y; (void)[=]() __attribute__((diagnose_if(!is_same, "wrong type", "warning"))){}(); // expected-warning@-1 {{wrong type}} expected-note@-1{{'diagnose_if' attribute on 'operator()'}} (void)[=]() __attribute__((diagnose_if(!is_same, "wrong type", "warning"))){}(); (void)[=]() __attribute__((diagnose_if(!is_same, "wrong type", "warning"))) mutable {}(); (void)[=]() __attribute__((diagnose_if(!is_same, "wrong type", "warning"))) mutable {}(); // expected-warning@-1 {{wrong type}} expected-note@-1{{'diagnose_if' attribute on 'operator()'}} (void)[x=1]() __attribute__((diagnose_if(!is_same, "wrong type", "warning"))){}(); // expected-warning@-1 {{wrong type}} expected-note@-1{{'diagnose_if' attribute on 'operator()'}} (void)[x=1]() __attribute__((diagnose_if(!is_same, "wrong type", "warning"))){}(); (void)[x=1]() __attribute__((diagnose_if(!is_same, "wrong type", "warning"))) mutable {}(); (void)[x=1]() __attribute__((diagnose_if(!is_same, "wrong type", "warning"))) mutable {}(); // expected-warning@-1 {{wrong type}} expected-note@-1{{'diagnose_if' attribute on 'operator()'}} } void nested() { int x, y, z; (void)[&]( decltype([&]( decltype([=]( decltype([&]( decltype([&](decltype(x)) {})) {})) {})) {})){}; (void)[&]( decltype([&]( decltype([&]( decltype([&]( decltype([&](decltype(y)) {})) {})) {})) {})){}; (void)[=]( decltype([=]( decltype([=]( decltype([=]( decltype([&] {})) {})) {})) {})){}; } template void dependent(U&& u) { [&]() requires is_same {}(); } template void dependent_init_capture(T x = 0) { [ y = x + 1, x ]() mutable -> decltype(y + x) requires(is_same && is_same) { return y; } (); [ y = x + 1, x ]() -> decltype(y + x) requires(is_same && is_same) { return y; } (); } template struct extract_type { using type = T; }; template void dependent_variadic_capture(T... x) { [... y = x, x... ](auto...) mutable -> typename extract_type::type requires((is_same && ...) && (is_same && ...)) { return 0; } (x...); [... y = x, x... ](auto...) -> typename extract_type::type requires((is_same && ...) && (is_same && ...)) { return 0; } (x...); } void test_dependent() { int v = 0; int & r = v; const int & cr = v; dependent(v); dependent(r); dependent(cr); dependent_init_capture(0); dependent_variadic_capture(1, 2, 3, 4); } void check_params() { int i = 0; int &j = i; (void)[=](decltype((j)) jp, decltype((i)) ip) { static_assert(is_same); static_assert(is_same); static_assert(is_same); static_assert(is_same); }; (void)[=](decltype((j)) jp, decltype((i)) ip) mutable { static_assert(is_same); static_assert(is_same); static_assert(is_same); static_assert(is_same); static_assert(is_same); static_assert(is_same); }; (void)[a = 0](decltype((a)) ap) mutable { static_assert(is_same); static_assert(is_same); static_assert(is_same); }; (void)[a = 0](decltype((a)) ap) { static_assert(is_same); static_assert(is_same); static_assert(is_same); }; } template void check_params_tpl() { T i = 0; T &j = i; (void)[=](decltype((j)) jp, decltype((i)) ip) { static_assert(is_same); static_assert(is_same); static_assert(is_same); static_assert(is_same); }; (void)[=](decltype((j)) jp, decltype((i)) ip) mutable { static_assert(is_same); static_assert(is_same); static_assert(is_same); static_assert(is_same); static_assert(is_same); static_assert(is_same); }; (void)[a = 0](decltype((a)) ap) mutable { static_assert(is_same); static_assert(is_same); static_assert(is_same); }; (void)[a = 0](decltype((a)) ap) { static_assert(is_same); static_assert(is_same); static_assert(is_same); }; }