15902bb95SChris Cotter // RUN: %check_clang_tidy %s cppcoreguidelines-missing-std-forward %t -- -- -fno-delayed-template-parsing 25902bb95SChris Cotter 35902bb95SChris Cotter // NOLINTBEGIN 45902bb95SChris Cotter namespace std { 55902bb95SChris Cotter 65902bb95SChris Cotter template <typename T> struct remove_reference { using type = T; }; 75902bb95SChris Cotter template <typename T> struct remove_reference<T&> { using type = T; }; 85902bb95SChris Cotter template <typename T> struct remove_reference<T&&> { using type = T; }; 95902bb95SChris Cotter 105902bb95SChris Cotter template <typename T> using remove_reference_t = typename remove_reference<T>::type; 115902bb95SChris Cotter 125902bb95SChris Cotter template <typename T> constexpr T &&forward(remove_reference_t<T> &t) noexcept; 135902bb95SChris Cotter template <typename T> constexpr T &&forward(remove_reference_t<T> &&t) noexcept; 145902bb95SChris Cotter template <typename T> constexpr remove_reference_t<T> &&move(T &&x); 155902bb95SChris Cotter 165902bb95SChris Cotter } // namespace std 175902bb95SChris Cotter // NOLINTEND 185902bb95SChris Cotter 195902bb95SChris Cotter struct S { 205902bb95SChris Cotter S(); 215902bb95SChris Cotter S(const S&); 225902bb95SChris Cotter S(S&&) noexcept; 235902bb95SChris Cotter S& operator=(const S&); 245902bb95SChris Cotter S& operator=(S&&) noexcept; 255902bb95SChris Cotter }; 265902bb95SChris Cotter 275902bb95SChris Cotter template <class... Ts> 285902bb95SChris Cotter void consumes_all(Ts&&...); 295902bb95SChris Cotter 305902bb95SChris Cotter namespace positive_cases { 315902bb95SChris Cotter 325902bb95SChris Cotter template <class T> 335902bb95SChris Cotter void does_not_forward(T&& t) { 345902bb95SChris Cotter // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 355902bb95SChris Cotter T other = t; 365902bb95SChris Cotter } 375902bb95SChris Cotter 385902bb95SChris Cotter template <class T> 395902bb95SChris Cotter void does_not_forward_invoked(T&& t) { 405902bb95SChris Cotter // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 415902bb95SChris Cotter T other = t(); 425902bb95SChris Cotter } 435902bb95SChris Cotter 445902bb95SChris Cotter template <class T> 455902bb95SChris Cotter void forwards_pairwise(T&& t) { 465902bb95SChris Cotter // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 475902bb95SChris Cotter auto first = std::forward<T>(t.first); 485902bb95SChris Cotter auto second = std::forward<T>(t.second); 495902bb95SChris Cotter } 505902bb95SChris Cotter 515902bb95SChris Cotter template <class... Ts> 525902bb95SChris Cotter void does_not_forward_pack(Ts&&... ts) { 535902bb95SChris Cotter // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: forwarding reference parameter 'ts' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 545902bb95SChris Cotter consumes_all(ts...); 555902bb95SChris Cotter } 565902bb95SChris Cotter 575902bb95SChris Cotter template <class T> 585902bb95SChris Cotter class AClass { 595902bb95SChris Cotter 605902bb95SChris Cotter template <class U> 615902bb95SChris Cotter AClass(U&& u) : data(u) {} 625902bb95SChris Cotter // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: forwarding reference parameter 'u' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 635902bb95SChris Cotter 645902bb95SChris Cotter template <class U> 655902bb95SChris Cotter AClass& operator=(U&& u) { } 665902bb95SChris Cotter // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: forwarding reference parameter 'u' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 675902bb95SChris Cotter 685902bb95SChris Cotter template <class U> 695902bb95SChris Cotter void mixed_params(T&& t, U&& u) { 705902bb95SChris Cotter // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: forwarding reference parameter 'u' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 715902bb95SChris Cotter T other1 = std::move(t); 725902bb95SChris Cotter U other2 = std::move(u); 735902bb95SChris Cotter } 745902bb95SChris Cotter 755902bb95SChris Cotter T data; 765902bb95SChris Cotter }; 775902bb95SChris Cotter 785902bb95SChris Cotter template <class T> 795902bb95SChris Cotter void does_not_forward_in_evaluated_code(T&& t) { 805902bb95SChris Cotter // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 815902bb95SChris Cotter using result_t = decltype(std::forward<T>(t)); 825902bb95SChris Cotter unsigned len = sizeof(std::forward<T>(t)); 835902bb95SChris Cotter T other = t; 845902bb95SChris Cotter } 855902bb95SChris Cotter 865902bb95SChris Cotter template <class T> 875902bb95SChris Cotter void lambda_value_capture(T&& t) { 885902bb95SChris Cotter // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 895902bb95SChris Cotter [=]() { T other = std::forward<T>(t); }; 905902bb95SChris Cotter } 915902bb95SChris Cotter 925902bb95SChris Cotter template <class T> 93d0848292SQizhi Hu void lambda_value_capture_copy(T&& t) { 94d0848292SQizhi Hu // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 95d0848292SQizhi Hu [&,t]() { T other = std::forward<T>(t); }; 965902bb95SChris Cotter } 975902bb95SChris Cotter 988b326d59SQizhi Hu template <typename X> 998b326d59SQizhi Hu void use(const X &x) {} 1008b326d59SQizhi Hu 1018b326d59SQizhi Hu template <typename X, typename Y> 1028b326d59SQizhi Hu void foo(X &&x, Y &&y) { 1038b326d59SQizhi Hu // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: forwarding reference parameter 'y' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 1048b326d59SQizhi Hu use(std::forward<X>(x)); 1058b326d59SQizhi Hu use(y); 1068b326d59SQizhi Hu } 1078b326d59SQizhi Hu 1085902bb95SChris Cotter } // namespace positive_cases 1095902bb95SChris Cotter 1105902bb95SChris Cotter namespace negative_cases { 1115902bb95SChris Cotter 1125902bb95SChris Cotter template <class T> 1135902bb95SChris Cotter void just_a_decl(T&&t); 1145902bb95SChris Cotter 1155902bb95SChris Cotter template <class T> 1165902bb95SChris Cotter void does_forward(T&& t) { 1175902bb95SChris Cotter T other = std::forward<T>(t); 1185902bb95SChris Cotter } 1195902bb95SChris Cotter 1205902bb95SChris Cotter template <class... Ts> 1215902bb95SChris Cotter void does_forward_pack(Ts&&... ts) { 1225902bb95SChris Cotter consumes_all(std::forward<Ts>(ts)...); 1235902bb95SChris Cotter } 1245902bb95SChris Cotter 1255902bb95SChris Cotter void pass_by_value(S s) { 1265902bb95SChris Cotter S other = std::move(s); 1275902bb95SChris Cotter } 1285902bb95SChris Cotter 1295902bb95SChris Cotter void lvalue_ref(S& s) { 1305902bb95SChris Cotter S other = std::move(s); 1315902bb95SChris Cotter } 1325902bb95SChris Cotter 1335902bb95SChris Cotter void rvalue_ref(S&& s) { 1345902bb95SChris Cotter S other = std::move(s); 1355902bb95SChris Cotter } 1365902bb95SChris Cotter 1375902bb95SChris Cotter template <class T> 1385902bb95SChris Cotter void templated_rvalue_ref(std::remove_reference_t<T>&& t) { 1395902bb95SChris Cotter T other = std::move(t); 1405902bb95SChris Cotter } 1415902bb95SChris Cotter 1425902bb95SChris Cotter template <class T> 1435902bb95SChris Cotter class AClass { 1445902bb95SChris Cotter 1455902bb95SChris Cotter template <class U> 1465902bb95SChris Cotter AClass(U&& u) : data(std::forward<U>(u)) {} 1475902bb95SChris Cotter 1485902bb95SChris Cotter template <class U> 1495902bb95SChris Cotter AClass& operator=(U&& u) { 1505902bb95SChris Cotter data = std::forward<U>(u); 1515902bb95SChris Cotter } 1525902bb95SChris Cotter 1535902bb95SChris Cotter void rvalue_ref(T&& t) { 1545902bb95SChris Cotter T other = std::move(t); 1555902bb95SChris Cotter } 1565902bb95SChris Cotter 1575902bb95SChris Cotter T data; 1585902bb95SChris Cotter }; 1595902bb95SChris Cotter 160d0848292SQizhi Hu template <class T> 161d0848292SQizhi Hu void lambda_value_reference(T&& t) { 162d0848292SQizhi Hu [&]() { T other = std::forward<T>(t); }; 163d0848292SQizhi Hu } 164d0848292SQizhi Hu 165d0848292SQizhi Hu template<typename T> 166d0848292SQizhi Hu void lambda_value_reference_capture_list_ref_1(T&& t) { 167d0848292SQizhi Hu [=, &t] { T other = std::forward<T>(t); }; 168d0848292SQizhi Hu } 169d0848292SQizhi Hu 170d0848292SQizhi Hu template<typename T> 171d0848292SQizhi Hu void lambda_value_reference_capture_list_ref_2(T&& t) { 172d0848292SQizhi Hu [&t] { T other = std::forward<T>(t); }; 173d0848292SQizhi Hu } 174d0848292SQizhi Hu 175d0848292SQizhi Hu template<typename T> 176d0848292SQizhi Hu void lambda_value_reference_capture_list(T&& t) { 177d0848292SQizhi Hu [t = std::forward<T>(t)] { t(); }; 178d0848292SQizhi Hu } 179d0848292SQizhi Hu 180d0848292SQizhi Hu template <class T> 181d0848292SQizhi Hu void lambda_value_reference_auxiliary_var(T&& t) { 182d0848292SQizhi Hu [&x = t]() { T other = std::forward<T>(x); }; 183d0848292SQizhi Hu } 184d0848292SQizhi Hu 1855902bb95SChris Cotter } // namespace negative_cases 1867b11e2ecSAMS21 1877b11e2ecSAMS21 namespace deleted_functions { 1887b11e2ecSAMS21 1897b11e2ecSAMS21 template <typename T> 190*2f321facSJulian Schmidt void f(T &&t) = delete; 1917b11e2ecSAMS21 1927b11e2ecSAMS21 struct S { 1937b11e2ecSAMS21 template <typename T> 194*2f321facSJulian Schmidt S(T &&t) = delete; 1957b11e2ecSAMS21 1967b11e2ecSAMS21 template <typename T> 197*2f321facSJulian Schmidt void operator&(T &&t) = delete; 1987b11e2ecSAMS21 }; 1997b11e2ecSAMS21 2007b11e2ecSAMS21 } // namespace deleted_functions 20116b3e43aSDanny Mösch 20216b3e43aSDanny Mösch namespace unused_arguments { 20316b3e43aSDanny Mösch 20416b3e43aSDanny Mösch template<typename F> 20516b3e43aSDanny Mösch void unused_argument1(F&&) {} 20616b3e43aSDanny Mösch 20716b3e43aSDanny Mösch template<typename F> 20816b3e43aSDanny Mösch void unused_argument2([[maybe_unused]] F&& f) {} 20916b3e43aSDanny Mösch 21016b3e43aSDanny Mösch template<typename F> 21116b3e43aSDanny Mösch void unused_argument3(F&& _) {} 21216b3e43aSDanny Mösch 21316b3e43aSDanny Mösch } // namespace unused_arguments 214