1 | // RUN: %check_clang_tidy -std=c++14-or-later %s readability-container-size-empty %t -- \ |
2 | // RUN: -config="{CheckOptions: {readability-container-size-empty.ExcludedComparisonTypes: '::std::array;::IgnoredDummyType'}}" \ |
3 | // RUN: -- -fno-delayed-template-parsing -isystem %clang_tidy_headers |
4 | #include <string> |
5 | |
6 | namespace std { |
7 | template <typename T> struct vector { |
8 | vector(); |
9 | bool operator==(const vector<T>& other) const; |
10 | bool operator!=(const vector<T>& other) const; |
11 | unsigned long size() const; |
12 | bool empty() const; |
13 | }; |
14 | |
15 | inline namespace __v2 { |
16 | template <typename T> struct set { |
17 | set(); |
18 | bool operator==(const set<T>& other) const; |
19 | bool operator!=(const set<T>& other) const; |
20 | unsigned long size() const; |
21 | bool empty() const; |
22 | }; |
23 | } |
24 | |
25 | namespace string_literals{ |
26 | string operator""s (const char *, size_t); |
27 | } |
28 | |
29 | } |
30 | |
31 | template <typename T> |
32 | class TemplatedContainer { |
33 | public: |
34 | bool operator==(const TemplatedContainer<T>& other) const; |
35 | bool operator!=(const TemplatedContainer<T>& other) const; |
36 | unsigned long size() const; |
37 | bool empty() const; |
38 | }; |
39 | |
40 | template <typename T> |
41 | class PrivateEmpty { |
42 | public: |
43 | bool operator==(const PrivateEmpty<T>& other) const; |
44 | bool operator!=(const PrivateEmpty<T>& other) const; |
45 | unsigned long size() const; |
46 | private: |
47 | bool empty() const; |
48 | }; |
49 | |
50 | struct BoolSize { |
51 | bool size() const; |
52 | bool empty() const; |
53 | }; |
54 | |
55 | struct EnumSize { |
56 | enum E { one }; |
57 | enum E size() const; |
58 | bool empty() const; |
59 | }; |
60 | |
61 | class Container { |
62 | public: |
63 | bool operator==(const Container& other) const; |
64 | unsigned long size() const; |
65 | bool empty() const; |
66 | }; |
67 | |
68 | class Derived : public Container { |
69 | }; |
70 | |
71 | class Container2 { |
72 | public: |
73 | unsigned long size() const; |
74 | bool empty() const { return size() == 0; } |
75 | }; |
76 | |
77 | class Container3 { |
78 | public: |
79 | unsigned long size() const; |
80 | bool empty() const; |
81 | }; |
82 | |
83 | bool Container3::empty() const { return this->size() == 0; } |
84 | |
85 | class Container4 { |
86 | public: |
87 | bool operator==(const Container4& rhs) const; |
88 | unsigned long size() const; |
89 | bool empty() const { return *this == Container4(); } |
90 | }; |
91 | |
92 | struct Lazy { |
93 | constexpr unsigned size() const { return 0; } |
94 | constexpr bool empty() const { return true; } |
95 | }; |
96 | |
97 | std::string s_func() { |
98 | return std::string(); |
99 | } |
100 | |
101 | void takesBool(bool) |
102 | { |
103 | |
104 | } |
105 | |
106 | bool returnsBool() { |
107 | std::set<int> intSet; |
108 | std::string str; |
109 | std::string str2; |
110 | std::wstring wstr; |
111 | (void)(str.size() + 0); |
112 | (void)(str.length() + 0); |
113 | (void)(str.size() - 0); |
114 | (void)(str.length() - 0); |
115 | (void)(0 + str.size()); |
116 | (void)(0 + str.length()); |
117 | (void)(0 - str.size()); |
118 | (void)(0 - str.length()); |
119 | if (intSet.size() == 0) |
120 | ; |
121 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
122 | // CHECK-FIXES: {{^ }}if (intSet.empty()){{$}} |
123 | // CHECK-MESSAGES: :21:8: note: method 'set'::empty() defined here |
124 | if (intSet == std::set<int>()) |
125 | ; |
126 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness |
127 | // CHECK-FIXES: {{^ }}if (intSet.empty()){{$}} |
128 | // CHECK-MESSAGES: :21:8: note: method 'set'::empty() defined here |
129 | if (s_func() == "" ) |
130 | ; |
131 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
132 | // CHECK-FIXES: {{^ }}if (s_func().empty()){{$}} |
133 | if (str.size() == 0) |
134 | ; |
135 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' |
136 | // CHECK-FIXES: {{^ }}if (str.empty()){{$}} |
137 | if (str.length() == 0) |
138 | ; |
139 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'length' |
140 | // CHECK-FIXES: {{^ }}if (str.empty()){{$}} |
141 | if ((str + str2).size() == 0) |
142 | ; |
143 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' |
144 | // CHECK-FIXES: {{^ }}if ((str + str2).empty()){{$}} |
145 | if ((str + str2).length() == 0) |
146 | ; |
147 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'length' |
148 | // CHECK-FIXES: {{^ }}if ((str + str2).empty()){{$}} |
149 | if (str == "" ) |
150 | ; |
151 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
152 | // CHECK-FIXES: {{^ }}if (str.empty()){{$}} |
153 | if (str + str2 == "" ) |
154 | ; |
155 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
156 | // CHECK-FIXES: {{^ }}if ((str + str2).empty()){{$}} |
157 | if (wstr.size() == 0) |
158 | ; |
159 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' |
160 | // CHECK-FIXES: {{^ }}if (wstr.empty()){{$}} |
161 | if (wstr.length() == 0) |
162 | ; |
163 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'length' |
164 | // CHECK-FIXES: {{^ }}if (wstr.empty()){{$}} |
165 | if (wstr == L"" ) |
166 | ; |
167 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
168 | // CHECK-FIXES: {{^ }}if (wstr.empty()){{$}} |
169 | std::vector<int> vect; |
170 | if (vect.size() == 0) |
171 | ; |
172 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' |
173 | // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} |
174 | if (vect == std::vector<int>()) |
175 | ; |
176 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
177 | // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} |
178 | if (vect.size() != 0) |
179 | ; |
180 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
181 | // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} |
182 | if (vect != std::vector<int>()) |
183 | ; |
184 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
185 | // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} |
186 | if (0 == vect.size()) |
187 | ; |
188 | // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used |
189 | // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} |
190 | if (0 != vect.size()) |
191 | ; |
192 | // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used |
193 | // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} |
194 | if (std::vector<int>() == vect) |
195 | ; |
196 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
197 | // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} |
198 | if (std::vector<int>() != vect) |
199 | ; |
200 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
201 | // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} |
202 | if (vect.size() > 0) |
203 | ; |
204 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
205 | // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} |
206 | if (0 < vect.size()) |
207 | ; |
208 | // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used |
209 | // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} |
210 | if (vect.size() < 1) |
211 | ; |
212 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
213 | // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} |
214 | if (1 > vect.size()) |
215 | ; |
216 | // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used |
217 | // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} |
218 | if (vect.size() >= 1) |
219 | ; |
220 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
221 | // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} |
222 | if (1 <= vect.size()) |
223 | ; |
224 | // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used |
225 | // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} |
226 | if (vect.size() > 1) // no warning |
227 | ; |
228 | if (1 < vect.size()) // no warning |
229 | ; |
230 | if (vect.size() <= 1) // no warning |
231 | ; |
232 | if (1 >= vect.size()) // no warning |
233 | ; |
234 | if (!vect.size()) |
235 | ; |
236 | // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used |
237 | // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} |
238 | if (vect.size()) |
239 | ; |
240 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
241 | // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} |
242 | |
243 | if (vect.empty()) |
244 | ; |
245 | |
246 | const std::vector<int> vect2; |
247 | if (vect2.size() != 0) |
248 | ; |
249 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
250 | // CHECK-FIXES: {{^ }}if (!vect2.empty()){{$}} |
251 | |
252 | std::vector<int> *vect3 = new std::vector<int>(); |
253 | if (vect3->size() == 0) |
254 | ; |
255 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
256 | // CHECK-FIXES: {{^ }}if (vect3->empty()){{$}} |
257 | if ((*vect3).size() == 0) |
258 | ; |
259 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
260 | // CHECK-FIXES: {{^ }}if ((*vect3).empty()){{$}} |
261 | if ((*vect3) == std::vector<int>()) |
262 | ; |
263 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
264 | // CHECK-FIXES: {{^ }}if (vect3->empty()){{$}} |
265 | if (*vect3 == std::vector<int>()) |
266 | ; |
267 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
268 | // CHECK-FIXES: {{^ }}if (vect3->empty()){{$}} |
269 | |
270 | delete vect3; |
271 | |
272 | const std::vector<int> &vect4 = vect2; |
273 | if (vect4.size() == 0) |
274 | ; |
275 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
276 | // CHECK-FIXES: {{^ }}if (vect4.empty()){{$}} |
277 | if (vect4 == std::vector<int>()) |
278 | ; |
279 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
280 | // CHECK-FIXES: {{^ }}if (vect4.empty()){{$}} |
281 | |
282 | TemplatedContainer<void> templated_container; |
283 | if (templated_container.size() == 0) |
284 | ; |
285 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
286 | // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}} |
287 | if (templated_container == TemplatedContainer<void>()) |
288 | ; |
289 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
290 | // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}} |
291 | if (templated_container.size() != 0) |
292 | ; |
293 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
294 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
295 | if (templated_container != TemplatedContainer<void>()) |
296 | ; |
297 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
298 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
299 | if (0 == templated_container.size()) |
300 | ; |
301 | // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used |
302 | // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}} |
303 | if (TemplatedContainer<void>() == templated_container) |
304 | ; |
305 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
306 | // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}} |
307 | if (0 != templated_container.size()) |
308 | ; |
309 | // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used |
310 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
311 | if (TemplatedContainer<void>() != templated_container) |
312 | ; |
313 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
314 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
315 | if (templated_container.size() > 0) |
316 | ; |
317 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
318 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
319 | if (0 < templated_container.size()) |
320 | ; |
321 | // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used |
322 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
323 | if (templated_container.size() < 1) |
324 | ; |
325 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
326 | // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}} |
327 | if (1 > templated_container.size()) |
328 | ; |
329 | // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used |
330 | // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}} |
331 | if (templated_container.size() >= 1) |
332 | ; |
333 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
334 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
335 | if (1 <= templated_container.size()) |
336 | ; |
337 | // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used |
338 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
339 | if (templated_container.size() > 1) // no warning |
340 | ; |
341 | if (1 < templated_container.size()) // no warning |
342 | ; |
343 | if (templated_container.size() <= 1) // no warning |
344 | ; |
345 | if (1 >= templated_container.size()) // no warning |
346 | ; |
347 | if (!templated_container.size()) |
348 | ; |
349 | // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used |
350 | // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}} |
351 | if (templated_container.size()) |
352 | ; |
353 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
354 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
355 | |
356 | if (templated_container.empty()) |
357 | ; |
358 | |
359 | // No warnings expected. |
360 | PrivateEmpty<void> private_empty; |
361 | if (private_empty.size() == 0) |
362 | ; |
363 | if (private_empty == PrivateEmpty<void>()) |
364 | ; |
365 | if (private_empty.size() != 0) |
366 | ; |
367 | if (private_empty != PrivateEmpty<void>()) |
368 | ; |
369 | if (0 == private_empty.size()) |
370 | ; |
371 | if (PrivateEmpty<void>() == private_empty) |
372 | ; |
373 | if (0 != private_empty.size()) |
374 | ; |
375 | if (PrivateEmpty<void>() != private_empty) |
376 | ; |
377 | if (private_empty.size() > 0) |
378 | ; |
379 | if (0 < private_empty.size()) |
380 | ; |
381 | if (private_empty.size() < 1) |
382 | ; |
383 | if (1 > private_empty.size()) |
384 | ; |
385 | if (private_empty.size() >= 1) |
386 | ; |
387 | if (1 <= private_empty.size()) |
388 | ; |
389 | if (private_empty.size() > 1) |
390 | ; |
391 | if (1 < private_empty.size()) |
392 | ; |
393 | if (private_empty.size() <= 1) |
394 | ; |
395 | if (1 >= private_empty.size()) |
396 | ; |
397 | if (!private_empty.size()) |
398 | ; |
399 | if (private_empty.size()) |
400 | ; |
401 | |
402 | // Types with weird size() return type. |
403 | BoolSize bs; |
404 | if (bs.size() == 0) |
405 | ; |
406 | EnumSize es; |
407 | if (es.size() == 0) |
408 | ; |
409 | |
410 | Derived derived; |
411 | if (derived.size() == 0) |
412 | ; |
413 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
414 | // CHECK-FIXES: {{^ }}if (derived.empty()){{$}} |
415 | if (derived == Derived()) |
416 | ; |
417 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
418 | // CHECK-FIXES: {{^ }}if (derived.empty()){{$}} |
419 | |
420 | takesBool(derived.size()); |
421 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used |
422 | // CHECK-FIXES: {{^ }}takesBool(!derived.empty()); |
423 | |
424 | takesBool(derived.size() == 0); |
425 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used |
426 | // CHECK-FIXES: {{^ }}takesBool(derived.empty()); |
427 | |
428 | takesBool(derived.size() != 0); |
429 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used |
430 | // CHECK-FIXES: {{^ }}takesBool(!derived.empty()); |
431 | |
432 | bool b1 = derived.size(); |
433 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used |
434 | // CHECK-FIXES: {{^ }}bool b1 = !derived.empty(); |
435 | |
436 | bool b2(derived.size()); |
437 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the 'empty' method should be used |
438 | // CHECK-FIXES: {{^ }}bool b2(!derived.empty()); |
439 | |
440 | auto b3 = static_cast<bool>(derived.size()); |
441 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: the 'empty' method should be used |
442 | // CHECK-FIXES: {{^ }}auto b3 = static_cast<bool>(!derived.empty()); |
443 | |
444 | auto b4 = (bool)derived.size(); |
445 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: the 'empty' method should be used |
446 | // CHECK-FIXES: {{^ }}auto b4 = (bool)!derived.empty(); |
447 | |
448 | auto b5 = bool(derived.size()); |
449 | // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: the 'empty' method should be used |
450 | // CHECK-FIXES: {{^ }}auto b5 = bool(!derived.empty()); |
451 | |
452 | return derived.size(); |
453 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used |
454 | // CHECK-FIXES: {{^ }}return !derived.empty(); |
455 | } |
456 | |
457 | class ConstructWithBoolField { |
458 | bool B; |
459 | public: |
460 | ConstructWithBoolField(const std::vector<int> &C) : B(C.size()) {} |
461 | // CHECK-MESSAGES: :[[@LINE-1]]:57: warning: the 'empty' method should be used |
462 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
463 | // CHECK-FIXES: {{^ }}ConstructWithBoolField(const std::vector<int> &C) : B(!C.empty()) {} |
464 | }; |
465 | |
466 | struct StructWithNSDMI { |
467 | std::vector<int> C; |
468 | bool B = C.size(); |
469 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: the 'empty' method should be used |
470 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
471 | // CHECK-FIXES: {{^ }}bool B = !C.empty(); |
472 | }; |
473 | |
474 | int func(const std::vector<int> &C) { |
475 | return C.size() ? 0 : 1; |
476 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used |
477 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
478 | // CHECK-FIXES: {{^ }}return !C.empty() ? 0 : 1; |
479 | } |
480 | |
481 | constexpr Lazy L; |
482 | static_assert(!L.size(), "" ); |
483 | // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: the 'empty' method should be used |
484 | // CHECK-MESSAGES: :94:18: note: method 'Lazy'::empty() defined here |
485 | // CHECK-FIXES: {{^}}static_assert(L.empty(), ""); |
486 | |
487 | struct StructWithLazyNoexcept { |
488 | void func() noexcept(L.size()); |
489 | }; |
490 | |
491 | #define CHECKSIZE(x) if (x.size()) {} |
492 | // CHECK-FIXES: #define CHECKSIZE(x) if (x.size()) {} |
493 | |
494 | template <typename T> void f() { |
495 | std::vector<T> v; |
496 | if (v.size()) |
497 | ; |
498 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
499 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
500 | // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} |
501 | if (v == std::vector<T>()) |
502 | ; |
503 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of comparing to an empty object [readability-container-size-empty] |
504 | // CHECK-FIXES: {{^ }}if (v.empty()){{$}} |
505 | // CHECK-FIXES-NEXT: ; |
506 | CHECKSIZE(v); |
507 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used |
508 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
509 | // CHECK-FIXES: CHECKSIZE(v); |
510 | |
511 | TemplatedContainer<T> templated_container; |
512 | if (templated_container.size()) |
513 | ; |
514 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
515 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
516 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
517 | if (templated_container != TemplatedContainer<T>()) |
518 | ; |
519 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
520 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
521 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
522 | // CHECK-FIXES-NEXT: ; |
523 | CHECKSIZE(templated_container); |
524 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used |
525 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
526 | // CHECK-FIXES: CHECKSIZE(templated_container); |
527 | std::basic_string<T> s; |
528 | if (s.size()) |
529 | ; |
530 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
531 | // CHECK-MESSAGES: string:{{[0-9]+}}:8: note: method 'basic_string'::empty() defined here |
532 | // CHECK-FIXES: {{^ }}if (!s.empty()){{$}} |
533 | if (s.length()) |
534 | ; |
535 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'length' [readability-container-size-empty] |
536 | // CHECK-MESSAGES: string:{{[0-9]+}}:8: note: method 'basic_string'::empty() defined here |
537 | // CHECK-FIXES: {{^ }}if (!s.empty()){{$}} |
538 | } |
539 | |
540 | void g() { |
541 | f<int>(); |
542 | f<double>(); |
543 | f<char *>(); |
544 | } |
545 | |
546 | template <typename T> |
547 | bool neverInstantiatedTemplate() { |
548 | std::vector<T> v; |
549 | if (v.size()) |
550 | ; |
551 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
552 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
553 | // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} |
554 | |
555 | if (v == std::vector<T>()) |
556 | ; |
557 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of comparing to an empty object [readability-container-size-empty] |
558 | // CHECK-FIXES: {{^ }}if (v.empty()){{$}} |
559 | // CHECK-FIXES-NEXT: ; |
560 | if (v.size() == 0) |
561 | ; |
562 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
563 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
564 | // CHECK-FIXES: {{^ }}if (v.empty()){{$}} |
565 | if (v.size() != 0) |
566 | ; |
567 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
568 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
569 | // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} |
570 | if (v.size() < 1) |
571 | ; |
572 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
573 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
574 | // CHECK-FIXES: {{^ }}if (v.empty()){{$}} |
575 | if (v.size() > 0) |
576 | ; |
577 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
578 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
579 | // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} |
580 | if (v.size() == 1) |
581 | ; |
582 | if (v.size() != 1) |
583 | ; |
584 | if (v.size() == 2) |
585 | ; |
586 | if (v.size() != 2) |
587 | ; |
588 | |
589 | if (static_cast<bool>(v.size())) |
590 | ; |
591 | // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
592 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
593 | // CHECK-FIXES: {{^ }}if (static_cast<bool>(!v.empty())){{$}} |
594 | if (v.size() && false) |
595 | ; |
596 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
597 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
598 | // CHECK-FIXES: {{^ }}if (!v.empty() && false){{$}} |
599 | if (!v.size()) |
600 | ; |
601 | // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
602 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
603 | // CHECK-FIXES: {{^ }}if (v.empty()){{$}} |
604 | |
605 | TemplatedContainer<T> templated_container; |
606 | if (templated_container.size()) |
607 | ; |
608 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
609 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
610 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
611 | if (templated_container != TemplatedContainer<T>()) |
612 | ; |
613 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
614 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
615 | // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} |
616 | // CHECK-FIXES-NEXT: ; |
617 | while (templated_container.size()) |
618 | ; |
619 | // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: the 'empty' method should be used |
620 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
621 | // CHECK-FIXES: {{^ }}while (!templated_container.empty()){{$}} |
622 | |
623 | do { |
624 | } |
625 | while (templated_container.size()); |
626 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used |
627 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
628 | // CHECK-FIXES: {{^ }}while (!templated_container.empty()); |
629 | |
630 | for (; templated_container.size();) |
631 | ; |
632 | // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: the 'empty' method should be used |
633 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
634 | // CHECK-FIXES: {{^ }}for (; !templated_container.empty();){{$}} |
635 | |
636 | if (true && templated_container.size()) |
637 | ; |
638 | // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: the 'empty' method should be used |
639 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
640 | // CHECK-FIXES: {{^ }}if (true && !templated_container.empty()){{$}} |
641 | |
642 | if (true || templated_container.size()) |
643 | ; |
644 | // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: the 'empty' method should be used |
645 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
646 | // CHECK-FIXES: {{^ }}if (true || !templated_container.empty()){{$}} |
647 | |
648 | if (!templated_container.size()) |
649 | ; |
650 | // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used |
651 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
652 | // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}} |
653 | |
654 | bool b1 = templated_container.size(); |
655 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used |
656 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
657 | // CHECK-FIXES: {{^ }}bool b1 = !templated_container.empty(); |
658 | |
659 | bool b2(templated_container.size()); |
660 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the 'empty' method should be used |
661 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
662 | // CHECK-FIXES: {{^ }}bool b2(!templated_container.empty()); |
663 | |
664 | auto b3 = static_cast<bool>(templated_container.size()); |
665 | // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: the 'empty' method should be used |
666 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
667 | // CHECK-FIXES: {{^ }}auto b3 = static_cast<bool>(!templated_container.empty()); |
668 | |
669 | auto b4 = (bool)templated_container.size(); |
670 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: the 'empty' method should be used |
671 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
672 | // CHECK-FIXES: {{^ }}auto b4 = (bool)!templated_container.empty(); |
673 | |
674 | auto b5 = bool(templated_container.size()); |
675 | // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: the 'empty' method should be used |
676 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
677 | // CHECK-FIXES: {{^ }}auto b5 = bool(!templated_container.empty()); |
678 | |
679 | takesBool(templated_container.size()); |
680 | // We don't detect this one because we don't know the parameter of takesBool |
681 | // until the type of templated_container.size() is known |
682 | |
683 | return templated_container.size(); |
684 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used |
685 | // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here |
686 | // CHECK-FIXES: {{^ }}return !templated_container.empty(); |
687 | } |
688 | |
689 | template <typename TypeRequiresSize> |
690 | void instantiatedTemplateWithSizeCall() { |
691 | TypeRequiresSize t; |
692 | // The instantiation of the template with std::vector<int> should not |
693 | // result in changing the template, because we don't know that |
694 | // TypeRequiresSize generally has `.empty()` |
695 | if (t.size()) |
696 | ; |
697 | |
698 | if (t == TypeRequiresSize{}) |
699 | ; |
700 | |
701 | if (t != TypeRequiresSize{}) |
702 | ; |
703 | } |
704 | |
705 | class TypeWithSize { |
706 | public: |
707 | TypeWithSize(); |
708 | bool operator==(const TypeWithSize &other) const; |
709 | bool operator!=(const TypeWithSize &other) const; |
710 | |
711 | unsigned size() const { return 0; } |
712 | // Does not have `.empty()` |
713 | }; |
714 | |
715 | void instantiator() { |
716 | instantiatedTemplateWithSizeCall<TypeWithSize>(); |
717 | instantiatedTemplateWithSizeCall<std::vector<int>>(); |
718 | } |
719 | |
720 | namespace std { |
721 | template <typename T> |
722 | struct unique_ptr { |
723 | T *operator->() const; |
724 | T &operator*() const; |
725 | }; |
726 | } // namespace std |
727 | |
728 | bool call_through_unique_ptr(const std::unique_ptr<std::vector<int>> &ptr) { |
729 | return ptr->size() > 0; |
730 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used |
731 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
732 | // CHECK-FIXES: {{^ }}return !ptr->empty(); |
733 | } |
734 | |
735 | bool call_through_unique_ptr_deref(const std::unique_ptr<std::vector<int>> &ptr) { |
736 | return (*ptr).size() > 0; |
737 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used |
738 | // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here |
739 | // CHECK-FIXES: {{^ }}return !(*ptr).empty(); |
740 | } |
741 | |
742 | struct TypedefSize { |
743 | typedef int size_type; |
744 | size_type size() const; |
745 | bool empty() const; |
746 | }; |
747 | |
748 | void testTypedefSize() { |
749 | TypedefSize ts; |
750 | if (ts.size() == 0) |
751 | ; |
752 | // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used |
753 | // CHECK-FIXES: {{^ }}if (ts.empty()){{$}} |
754 | } |
755 | |
756 | namespace std { |
757 | |
758 | template <typename T, unsigned long N> struct array { |
759 | bool operator==(const array& other) const; |
760 | bool operator!=(const array& other) const; |
761 | unsigned long size() const { return N; } |
762 | bool empty() const { return N != 0U; } |
763 | |
764 | T data[N]; |
765 | }; |
766 | |
767 | } |
768 | |
769 | struct DummyType { |
770 | bool operator==(const DummyType&) const; |
771 | unsigned long size() const; |
772 | bool empty() const; |
773 | }; |
774 | |
775 | struct IgnoredDummyType { |
776 | bool operator==(const IgnoredDummyType&) const; |
777 | unsigned long size() const; |
778 | bool empty() const; |
779 | }; |
780 | |
781 | typedef std::array<int, 10U> Array; |
782 | |
783 | bool testArraySize(const Array& value) { |
784 | return value.size() == 0U; |
785 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
786 | // CHECK-FIXES: {{^ }}return value.empty();{{$}} |
787 | // CHECK-MESSAGES: :[[@LINE-25]]:8: note: method 'array'::empty() defined here |
788 | } |
789 | |
790 | bool testArrayCompareToEmpty(const Array& value) { |
791 | return value == std::array<int, 10U>(); |
792 | } |
793 | |
794 | bool testDummyType(const DummyType& value) { |
795 | return value == DummyType(); |
796 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used to check for emptiness instead of comparing to an empty object [readability-container-size-empty] |
797 | // CHECK-FIXES: {{^ }}return value.empty();{{$}} |
798 | // CHECK-MESSAGES: :[[@LINE-26]]:8: note: method 'DummyType'::empty() defined here |
799 | } |
800 | |
801 | bool testIgnoredDummyType(const IgnoredDummyType& value) { |
802 | return value == IgnoredDummyType(); |
803 | } |
804 | |
805 | bool testStringLiterals(const std::string& s) |
806 | { |
807 | using namespace std::string_literals; |
808 | return s == ""s ; |
809 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used |
810 | // CHECK-FIXES: {{^ }}return s.empty() |
811 | } |
812 | |
813 | bool testNotEmptyStringLiterals(const std::string& s) |
814 | { |
815 | using namespace std::string_literals; |
816 | return s == "foo"s ; |
817 | } |
818 | |
819 | namespace PR72619 { |
820 | struct SS { |
821 | bool empty() const; |
822 | int size() const; |
823 | }; |
824 | |
825 | struct SU { |
826 | bool empty() const; |
827 | unsigned size() const; |
828 | }; |
829 | |
830 | void f(const SU& s) { |
831 | if (s.size() < 0) {} |
832 | if (0 > s.size()) {} |
833 | if (s.size() >= 0) {} |
834 | if (0 <= s.size()) {} |
835 | if (s.size() < 1) |
836 | ; |
837 | // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
838 | // CHECK-FIXES: {{^ }}if (s.empty()){{$}} |
839 | if (1 > s.size()) |
840 | ; |
841 | // CHECK-MESSAGES: :[[@LINE-2]]:13: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
842 | // CHECK-FIXES: {{^ }}if (s.empty()){{$}} |
843 | if (s.size() <= 0) |
844 | ; |
845 | // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
846 | // CHECK-FIXES: {{^ }}if (s.empty()){{$}} |
847 | if (0 >= s.size()) |
848 | ; |
849 | // CHECK-MESSAGES: :[[@LINE-2]]:14: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] |
850 | // CHECK-FIXES: {{^ }}if (s.empty()){{$}} |
851 | } |
852 | |
853 | void f(const SS& s) { |
854 | if (s.size() < 0) {} |
855 | if (0 > s.size()) {} |
856 | if (s.size() >= 0) {} |
857 | if (0 <= s.size()) {} |
858 | if (s.size() < 1) {} |
859 | if (1 > s.size()) {} |
860 | if (s.size() <= 0) {} |
861 | if (0 >= s.size()) {} |
862 | } |
863 | } |
864 | |