// RUN: %check_clang_tidy %s cppcoreguidelines-missing-std-forward %t -- -- -fno-delayed-template-parsing // NOLINTBEGIN namespace std { template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; template struct remove_reference { using type = T; }; template using remove_reference_t = typename remove_reference::type; template constexpr T &&forward(remove_reference_t &t) noexcept; template constexpr T &&forward(remove_reference_t &&t) noexcept; template constexpr remove_reference_t &&move(T &&x); } // namespace std // NOLINTEND struct S { S(); S(const S&); S(S&&) noexcept; S& operator=(const S&); S& operator=(S&&) noexcept; }; template void consumes_all(Ts&&...); namespace positive_cases { template void does_not_forward(T&& t) { // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] T other = t; } template void does_not_forward_invoked(T&& t) { // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] T other = t(); } template void forwards_pairwise(T&& t) { // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] auto first = std::forward(t.first); auto second = std::forward(t.second); } template void does_not_forward_pack(Ts&&... ts) { // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: forwarding reference parameter 'ts' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] consumes_all(ts...); } template class AClass { template AClass(U&& u) : data(u) {} // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: forwarding reference parameter 'u' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] template AClass& operator=(U&& u) { } // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: forwarding reference parameter 'u' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] template void mixed_params(T&& t, U&& u) { // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: forwarding reference parameter 'u' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] T other1 = std::move(t); U other2 = std::move(u); } T data; }; template void does_not_forward_in_evaluated_code(T&& t) { // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] using result_t = decltype(std::forward(t)); unsigned len = sizeof(std::forward(t)); T other = t; } template void lambda_value_capture(T&& t) { // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] [=]() { T other = std::forward(t); }; } template void lambda_value_capture_copy(T&& t) { // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] [&,t]() { T other = std::forward(t); }; } template void use(const X &x) {} template void foo(X &&x, Y &&y) { // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: forwarding reference parameter 'y' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] use(std::forward(x)); use(y); } } // namespace positive_cases namespace negative_cases { template void just_a_decl(T&&t); template void does_forward(T&& t) { T other = std::forward(t); } template void does_forward_pack(Ts&&... ts) { consumes_all(std::forward(ts)...); } void pass_by_value(S s) { S other = std::move(s); } void lvalue_ref(S& s) { S other = std::move(s); } void rvalue_ref(S&& s) { S other = std::move(s); } template void templated_rvalue_ref(std::remove_reference_t&& t) { T other = std::move(t); } template class AClass { template AClass(U&& u) : data(std::forward(u)) {} template AClass& operator=(U&& u) { data = std::forward(u); } void rvalue_ref(T&& t) { T other = std::move(t); } T data; }; template void lambda_value_reference(T&& t) { [&]() { T other = std::forward(t); }; } template void lambda_value_reference_capture_list_ref_1(T&& t) { [=, &t] { T other = std::forward(t); }; } template void lambda_value_reference_capture_list_ref_2(T&& t) { [&t] { T other = std::forward(t); }; } template void lambda_value_reference_capture_list(T&& t) { [t = std::forward(t)] { t(); }; } template void lambda_value_reference_auxiliary_var(T&& t) { [&x = t]() { T other = std::forward(x); }; } } // namespace negative_cases namespace deleted_functions { template void f(T &&t) = delete; struct S { template S(T &&t) = delete; template void operator&(T &&t) = delete; }; } // namespace deleted_functions namespace unused_arguments { template void unused_argument1(F&&) {} template void unused_argument2([[maybe_unused]] F&& f) {} template void unused_argument3(F&& _) {} } // namespace unused_arguments