File: rvalue-reference-param-not-moved.cpp

package info (click to toggle)
llvm-toolchain-17 1%3A17.0.6-22
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,799,624 kB
  • sloc: cpp: 6,428,607; ansic: 1,383,196; asm: 793,408; python: 223,504; objc: 75,364; f90: 60,502; lisp: 33,869; pascal: 15,282; sh: 9,684; perl: 7,453; ml: 4,937; awk: 3,523; makefile: 2,889; javascript: 2,149; xml: 888; fortran: 619; cs: 573
file content (335 lines) | stat: -rw-r--r-- 11,525 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
// RUN: %check_clang_tidy -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \
// RUN: -config="{CheckOptions: [{key: cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove, value: true},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams, value: true},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes, value: true}]}" -- -fno-delayed-template-parsing
// RUN: %check_clang_tidy -check-suffix=,CXX14 -std=c++14 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \
// RUN: -config="{CheckOptions: [{key: cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove, value: true},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams, value: true},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes, value: true}]}" -- -fno-delayed-template-parsing
// RUN: %check_clang_tidy -check-suffix=,NOSUBEXPR -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \
// RUN: -config="{CheckOptions: [{key: cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove, value: false},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams, value: true},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes, value: true}]}" -- -fno-delayed-template-parsing
// RUN: %check_clang_tidy -check-suffix=,UNNAMED -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \
// RUN: -config="{CheckOptions: [{key: cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove, value: true},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams, value: false},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes, value: true}]}" -- -fno-delayed-template-parsing
// RUN: %check_clang_tidy -check-suffix=,NONDEDUCED -std=c++11 %s cppcoreguidelines-rvalue-reference-param-not-moved %t -- \
// RUN: -config="{CheckOptions: [{key: cppcoreguidelines-rvalue-reference-param-not-moved.AllowPartialMove, value: true},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreUnnamedParams, value: true},{key: cppcoreguidelines-rvalue-reference-param-not-moved.IgnoreNonDeducedTemplateTypes, value: false}]}" -- -fno-delayed-template-parsing

// NOLINTBEGIN
namespace std {
template <typename>
struct remove_reference;

template <typename _Tp> struct remove_reference { typedef _Tp type; };
template <typename _Tp> struct remove_reference<_Tp&> { typedef _Tp type; };
template <typename _Tp> struct remove_reference<_Tp&&> { typedef _Tp type; };

template <typename _Tp>
constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept;

template <typename _Tp>
constexpr _Tp &&
forward(typename remove_reference<_Tp>::type &__t) noexcept;

}
// NOLINTEND

struct Obj {
  Obj();
  Obj(const Obj&);
  Obj& operator=(const Obj&);
  Obj(Obj&&);
  Obj& operator=(Obj&&);
  void member() const;
};

void consumes_object(Obj);

void never_moves_param(Obj&& o) {
  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
  o.member();
}

void just_a_declaration(Obj&& o);

void copies_object(Obj&& o) {
  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
  Obj copy = o;
}

template <typename T>
void never_moves_param_template(Obj&& o, T t) {
  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
  o.member();
}

void never_moves_params(Obj&& o1, Obj&& o2) {
  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
  // CHECK-MESSAGES: :[[@LINE-2]]:41: warning: rvalue reference parameter 'o2' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
}

void never_moves_some_params(Obj&& o1, Obj&& o2) {
  // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]

  Obj other{std::move(o2)};
}

void never_moves_unnamed(Obj&&) {}
// CHECK-MESSAGES-UNNAMED: :[[@LINE-1]]:31: warning: rvalue reference parameter '' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]

void never_moves_mixed(Obj o1, Obj&& o2) {
  // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: rvalue reference parameter 'o2' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
}

void lambda_captures_parameter_as_value(Obj&& o) {
  auto f = [o]() {
    consumes_object(std::move(o));
  };
  // CHECK-MESSAGES: :[[@LINE-4]]:47: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
}

void lambda_captures_parameter_as_value_nested(Obj&& o) {
  // CHECK-MESSAGES: :[[@LINE-1]]:54: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
  auto f = [&o]() {
    auto f_nested = [o]() {
      consumes_object(std::move(o));
    };
  };
  auto f2 = [o]() {
    auto f_nested = [&o]() {
      consumes_object(std::move(o));
    };
  };
  auto f3 = [o]() {
    auto f_nested = [&o]() {
      auto f_nested_inner = [&o]() {
        consumes_object(std::move(o));
      };
    };
  };
  auto f4 = [&o]() {
    auto f_nested = [&o]() {
      auto f_nested_inner = [o]() {
        consumes_object(std::move(o));
      };
    };
  };
}

void misc_lambda_checks() {
  auto never_moves = [](Obj&& o1) {
    Obj other{o1};
  };
  // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]

#if __cplusplus >= 201402L
  auto never_moves_with_auto_param = [](Obj&& o1, auto& v) {
    Obj other{o1};
  };
  // CHECK-MESSAGES-CXX14: :[[@LINE-3]]:47: warning: rvalue reference parameter 'o1' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
#endif
}

template <typename T>
void forwarding_ref(T&& t) {
  t.member();
}

template <typename T>
void forwarding_ref_forwarded(T&& t) {
  forwarding_ref(std::forward<T>(t));
}

template <typename... Ts>
void type_pack(Ts&&... ts) {
  (forwarding_ref(std::forward<Ts>(ts)), ...);
}

void call_forwarding_functions() {
  Obj o;

  forwarding_ref(Obj{});
  type_pack(Obj{});
  type_pack(Obj{}, o);
  type_pack(Obj{}, Obj{});
}

void moves_parameter(Obj&& o) {
  Obj moved = std::move(o);
}

void moves_parameter_extra_parens(Obj&& o) {
  Obj moved = std::move((o));
}

void does_not_move_in_evaluated(Obj&& o) {
  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
  using result_t = decltype(std::move(o));
  unsigned size = sizeof(std::move(o));
  Obj moved = o;
}

template <typename T1, typename T2>
struct mypair {
  T1 first;
  T2 second;
};

void moves_member_of_parameter(mypair<Obj, Obj>&& pair) {
  // CHECK-MESSAGES-NOSUBEXPR: :[[@LINE-1]]:51: warning: rvalue reference parameter 'pair' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
  Obj a = std::move(pair.first);
  Obj b = std::move(pair.second);
}

template <typename T>
struct myoptional {
  T& operator*() &;
  T&& operator*() &&;
};

void moves_deref_optional(myoptional<Obj>&& opt) {
  // CHECK-MESSAGES-NOSUBEXPR: :[[@LINE-1]]:45: warning: rvalue reference parameter 'opt' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
  Obj other = std::move(*opt);
}

void moves_optional_then_deref_resulting_rvalue(myoptional<Obj>&& opt) {
  Obj other = *std::move(opt);
}

void pass_by_lvalue_reference(Obj& o) {
  o.member();
}

void pass_by_value(Obj o) {
  o.member();
}

void pass_by_const_lvalue_reference(const Obj& o) {
  o.member();
}

void pass_by_const_lvalue_reference(const Obj&& o) {
  o.member();
}

void lambda_captures_parameter_as_reference(Obj&& o) {
  auto f = [&o]() {
    consumes_object(std::move(o));
  };
}

void lambda_captures_parameter_as_reference_nested(Obj&& o) {
  auto f = [&o]() {
    auto f_nested = [&o]() {
      auto f_nested2 = [&o]() {
        consumes_object(std::move(o));
      };
    };
  };
}

#if __cplusplus >= 201402L
void lambda_captures_parameter_generalized(Obj&& o) {
  auto f = [o = std::move(o)]() {
    consumes_object(std::move(o));
  };
}
#endif

void negative_lambda_checks() {
  auto never_moves_nested = [](Obj&& o1) {
    auto nested = [&]() {
      Obj other{std::move(o1)};
    };
  };

#if __cplusplus >= 201402L
  auto auto_lvalue_ref_param = [](auto& o1) {
    Obj other{o1};
  };

  auto auto_forwarding_ref_param = [](auto&& o1) {
    Obj other{o1};
  };

  auto does_move_auto_rvalue_ref_param = [](auto&& o1) {
    Obj other{std::forward(o1)};
  };
#endif

  auto does_move = [](Obj&& o1) {
    Obj other{std::move(o1)};
  };

  auto not_rvalue_ref = [](Obj& o1) {
    Obj other{std::move(o1)};
  };

  Obj local;
  auto captures = [local]() { };
}

struct AClass {
  void member_with_lambda_no_move(Obj&& o) {
    // CHECK-MESSAGES: :[[@LINE-1]]:41: warning: rvalue reference parameter 'o' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
    auto captures_this = [=, this]() {
      Obj other = std::move(o);
    };
  }
  void member_with_lambda_that_moves(Obj&& o) {
    auto captures_this = [&, this]() {
      Obj other = std::move(o);
    };
  }
};

void useless_move(Obj&& o) {
  // FIXME - The object is not actually moved from - this should probably be
  // flagged by *some* check. Which one?
  std::move(o);
}

template <typename>
class TemplatedClass;

template <typename T>
void unresolved_lookup(TemplatedClass<T>&& o) {
  TemplatedClass<T> moved = std::move(o);
}

struct DefinesMove {
  DefinesMove(DefinesMove&& rhs) : o(std::move(rhs.o)) { }
  DefinesMove& operator=(DefinesMove&& rhs) {
    if (this != &rhs) {
      o = std::move(rhs.o);
    }
    return *this;
  }
  Obj o;
};

struct DeclaresMove {
  DeclaresMove(DeclaresMove&& rhs);
  DeclaresMove& operator=(DeclaresMove&& rhs);
};

struct AnotherObj {
  AnotherObj(Obj&& o) : o(std::move(o)) {}
  AnotherObj(Obj&& o, int) { o = std::move(o); }
  Obj o;
};

template <class T>
struct AClassTemplate {
  AClassTemplate(T&& t) {}
  // CHECK-MESSAGES-NONDEDUCED: :[[@LINE-1]]:22: warning: rvalue reference parameter 't' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]

  void moves(T&& t) {
    T other = std::move(t);
  }
  void never_moves(T&& t) {}
  // CHECK-MESSAGES-NONDEDUCED: :[[@LINE-1]]:24: warning: rvalue reference parameter 't' is never moved from inside the function body [cppcoreguidelines-rvalue-reference-param-not-moved]
};

void instantiate_a_class_template() {
  Obj o;
  AClassTemplate<Obj> withObj{std::move(o)};
  withObj.never_moves(std::move(o));

  AClassTemplate<Obj&> withObjRef(o);
  withObjRef.never_moves(o);
}