1// RUN: %check_clang_tidy %s cppcoreguidelines-missing-std-forward %t -- -- -fno-delayed-template-parsing
2
3// NOLINTBEGIN
4namespace 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 std
17// NOLINTEND
18
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_cases
109
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_cases
186
187namespace deleted_functions {
188
189template <typename T>
190void f(T &&) = delete;
191
192struct S {
193 template <typename T>
194 S(T &&) = delete;
195
196 template <typename T>
197 void operator&(T &&) = delete;
198};
199
200} // namespace deleted_functions
201
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_arguments
214

source code of clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/missing-std-forward.cpp