214 lines · cpp
1// RUN: %check_clang_tidy %s cppcoreguidelines-missing-std-forward %t -- -- -fno-delayed-template-parsing2 3// NOLINTBEGIN4namespace std {5 6template <typename T> struct remove_reference { using type = T; };7template <typename T> struct remove_reference<T&> { using type = T; };8template <typename T> struct remove_reference<T&&> { using type = T; };9 10template <typename T> using remove_reference_t = typename remove_reference<T>::type;11 12template <typename T> constexpr T &&forward(remove_reference_t<T> &t) noexcept;13template <typename T> constexpr T &&forward(remove_reference_t<T> &&t) noexcept;14template <typename T> constexpr remove_reference_t<T> &&move(T &&x);15 16} // namespace std17// NOLINTEND18 19struct S {20 S();21 S(const S&);22 S(S&&) noexcept;23 S& operator=(const S&);24 S& operator=(S&&) noexcept;25};26 27template <class... Ts>28void consumes_all(Ts&&...);29 30namespace positive_cases {31 32template <class T>33void does_not_forward(T&& t) {34 // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]35 T other = t;36}37 38template <class T>39void does_not_forward_invoked(T&& t) {40 // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]41 T other = t();42}43 44template <class T>45void forwards_pairwise(T&& t) {46 // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]47 auto first = std::forward<T>(t.first);48 auto second = std::forward<T>(t.second);49}50 51template <class... Ts>52void does_not_forward_pack(Ts&&... ts) {53 // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: forwarding reference parameter 'ts' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]54 consumes_all(ts...);55}56 57template <class T>58class AClass {59 60 template <class U>61 AClass(U&& u) : data(u) {}62 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: forwarding reference parameter 'u' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]63 64 template <class U>65 AClass& operator=(U&& u) { }66 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: forwarding reference parameter 'u' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]67 68 template <class U>69 void mixed_params(T&& t, U&& u) {70 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: forwarding reference parameter 'u' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]71 T other1 = std::move(t);72 U other2 = std::move(u);73 }74 75 T data;76};77 78template <class T>79void does_not_forward_in_evaluated_code(T&& t) {80 // CHECK-MESSAGES: :[[@LINE-1]]:45: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]81 using result_t = decltype(std::forward<T>(t));82 unsigned len = sizeof(std::forward<T>(t));83 T other = t;84}85 86template <class T>87void lambda_value_capture(T&& t) {88 // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]89 [=]() { T other = std::forward<T>(t); };90}91 92template <class T>93void lambda_value_capture_copy(T&& t) {94 // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]95 [&,t]() { T other = std::forward<T>(t); };96}97 98template <typename X>99void use(const X &x) {}100 101template <typename X, typename Y>102void foo(X &&x, Y &&y) {103 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: forwarding reference parameter 'y' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]104 use(std::forward<X>(x));105 use(y);106}107 108} // namespace positive_cases109 110namespace negative_cases {111 112template <class T>113void just_a_decl(T&&t);114 115template <class T>116void does_forward(T&& t) {117 T other = std::forward<T>(t);118}119 120template <class... Ts>121void does_forward_pack(Ts&&... ts) {122 consumes_all(std::forward<Ts>(ts)...);123}124 125void pass_by_value(S s) {126 S other = std::move(s);127}128 129void lvalue_ref(S& s) {130 S other = std::move(s);131}132 133void rvalue_ref(S&& s) {134 S other = std::move(s);135}136 137template <class T>138void templated_rvalue_ref(std::remove_reference_t<T>&& t) {139 T other = std::move(t);140}141 142template <class T>143class AClass {144 145 template <class U>146 AClass(U&& u) : data(std::forward<U>(u)) {}147 148 template <class U>149 AClass& operator=(U&& u) {150 data = std::forward<U>(u);151 }152 153 void rvalue_ref(T&& t) {154 T other = std::move(t);155 }156 157 T data;158};159 160template <class T>161void lambda_value_reference(T&& t) {162 [&]() { T other = std::forward<T>(t); };163}164 165template<typename T>166void lambda_value_reference_capture_list_ref_1(T&& t) {167 [=, &t] { T other = std::forward<T>(t); };168}169 170template<typename T>171void lambda_value_reference_capture_list_ref_2(T&& t) {172 [&t] { T other = std::forward<T>(t); };173}174 175template<typename T>176void lambda_value_reference_capture_list(T&& t) {177 [t = std::forward<T>(t)] { t(); };178}179 180template <class T>181void lambda_value_reference_auxiliary_var(T&& t) {182 [&x = t]() { T other = std::forward<T>(x); };183}184 185} // namespace negative_cases186 187namespace deleted_functions {188 189template <typename T>190void f(T &&t) = delete;191 192struct S {193 template <typename T>194 S(T &&t) = delete;195 196 template <typename T>197 void operator&(T &&t) = delete;198};199 200} // namespace deleted_functions201 202namespace unused_arguments {203 204template<typename F>205void unused_argument1(F&&) {}206 207template<typename F>208void unused_argument2([[maybe_unused]] F&& f) {}209 210template<typename F>211void unused_argument3(F&& _) {}212 213} // namespace unused_arguments214