1 // RUN: %check_clang_tidy %s readability-container-size-empty %t -- -- -fno-delayed-template-parsing
2 
3 namespace std {
4 template <typename T> struct vector {
5   vector();
6   bool operator==(const vector<T>& other) const;
7   bool operator!=(const vector<T>& other) const;
8   unsigned long size() const;
9   bool empty() const;
10 };
11 
12 template <typename T> struct basic_string {
13   basic_string();
14   bool operator==(const basic_string<T>& other) const;
15   bool operator!=(const basic_string<T>& other) const;
16   bool operator==(const char *) const;
17   bool operator!=(const char *) const;
18   basic_string<T> operator+(const basic_string<T>& other) const;
19   unsigned long size() const;
20   bool empty() const;
21 };
22 
23 typedef basic_string<char> string;
24 typedef basic_string<wchar_t> wstring;
25 
26 inline namespace __v2 {
27 template <typename T> struct set {
28   set();
29   bool operator==(const set<T>& other) const;
30   bool operator!=(const set<T>& other) const;
31   unsigned long size() const;
32   bool empty() const;
33 };
34 }
35 
36 }
37 
38 template <typename T>
39 class TemplatedContainer {
40 public:
41   bool operator==(const TemplatedContainer<T>& other) const;
42   bool operator!=(const TemplatedContainer<T>& other) const;
43   int size() const;
44   bool empty() const;
45 };
46 
47 template <typename T>
48 class PrivateEmpty {
49 public:
50   bool operator==(const PrivateEmpty<T>& other) const;
51   bool operator!=(const PrivateEmpty<T>& other) const;
52   int size() const;
53 private:
54   bool empty() const;
55 };
56 
57 struct BoolSize {
58   bool size() const;
59   bool empty() const;
60 };
61 
62 struct EnumSize {
63   enum E { one };
64   enum E size() const;
65   bool empty() const;
66 };
67 
68 class Container {
69 public:
70   bool operator==(const Container& other) const;
71   int size() const;
72   bool empty() const;
73 };
74 
75 class Derived : public Container {
76 };
77 
78 class Container2 {
79 public:
80   int size() const;
empty() const81   bool empty() const { return size() == 0; }
82 };
83 
84 class Container3 {
85 public:
86   int size() const;
87   bool empty() const;
88 };
89 
empty() const90 bool Container3::empty() const { return this->size() == 0; }
91 
92 class Container4 {
93 public:
94   bool operator==(const Container4& rhs) const;
95   int size() const;
empty() const96   bool empty() const { return *this == Container4(); }
97 };
98 
99 struct Lazy {
sizeLazy100   constexpr unsigned size() const { return 0; }
emptyLazy101   constexpr bool empty() const { return true; }
102 };
103 
s_func()104 std::string s_func() {
105   return std::string();
106 }
107 
takesBool(bool)108 void takesBool(bool)
109 {
110 
111 }
112 
returnsBool()113 bool returnsBool() {
114   std::set<int> intSet;
115   std::string str;
116   std::string str2;
117   std::wstring wstr;
118   (void)(str.size() + 0);
119   (void)(str.size() - 0);
120   (void)(0 + str.size());
121   (void)(0 - str.size());
122   if (intSet.size() == 0)
123     ;
124   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
125   // CHECK-FIXES: {{^  }}if (intSet.empty()){{$}}
126   // CHECK-MESSAGES: :32:8: note: method 'set'::empty() defined here
127   if (intSet == std::set<int>())
128     ;
129   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness
130   // CHECK-FIXES: {{^  }}if (intSet.empty()){{$}}
131   // CHECK-MESSAGES: :32:8: note: method 'set'::empty() defined here
132   if (s_func() == "")
133     ;
134   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
135   // CHECK-FIXES: {{^  }}if (s_func().empty()){{$}}
136   if (str.size() == 0)
137     ;
138   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
139   // CHECK-FIXES: {{^  }}if (str.empty()){{$}}
140   if ((str + str2).size() == 0)
141     ;
142   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
143   // CHECK-FIXES: {{^  }}if ((str + str2).empty()){{$}}
144   if (str == "")
145     ;
146   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
147   // CHECK-FIXES: {{^  }}if (str.empty()){{$}}
148   if (str + str2 == "")
149     ;
150   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
151   // CHECK-FIXES: {{^  }}if ((str + str2).empty()){{$}}
152   if (wstr.size() == 0)
153     ;
154   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
155   // CHECK-FIXES: {{^  }}if (wstr.empty()){{$}}
156   if (wstr == "")
157     ;
158   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
159   // CHECK-FIXES: {{^  }}if (wstr.empty()){{$}}
160   std::vector<int> vect;
161   if (vect.size() == 0)
162     ;
163   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
164   // CHECK-FIXES: {{^  }}if (vect.empty()){{$}}
165   if (vect == std::vector<int>())
166     ;
167   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
168   // CHECK-FIXES: {{^  }}if (vect.empty()){{$}}
169   if (vect.size() != 0)
170     ;
171   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
172   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
173   if (vect != std::vector<int>())
174     ;
175   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
176   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
177   if (0 == vect.size())
178     ;
179   // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
180   // CHECK-FIXES: {{^  }}if (vect.empty()){{$}}
181   if (0 != vect.size())
182     ;
183   // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
184   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
185   if (std::vector<int>() == vect)
186     ;
187   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
188   // CHECK-FIXES: {{^  }}if (vect.empty()){{$}}
189   if (std::vector<int>() != vect)
190     ;
191   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
192   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
193   if (vect.size() > 0)
194     ;
195   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
196   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
197   if (0 < vect.size())
198     ;
199   // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used
200   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
201   if (vect.size() < 1)
202     ;
203   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
204   // CHECK-FIXES: {{^  }}if (vect.empty()){{$}}
205   if (1 > vect.size())
206     ;
207   // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used
208   // CHECK-FIXES: {{^  }}if (vect.empty()){{$}}
209   if (vect.size() >= 1)
210     ;
211   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
212   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
213   if (1 <= vect.size())
214     ;
215   // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
216   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
217   if (vect.size() > 1) // no warning
218     ;
219   if (1 < vect.size()) // no warning
220     ;
221   if (vect.size() <= 1) // no warning
222     ;
223   if (1 >= vect.size()) // no warning
224     ;
225   if (!vect.size())
226     ;
227   // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used
228   // CHECK-FIXES: {{^  }}if (vect.empty()){{$}}
229   if (vect.size())
230     ;
231   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
232   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
233 
234   if (vect.empty())
235     ;
236 
237   const std::vector<int> vect2;
238   if (vect2.size() != 0)
239     ;
240   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
241   // CHECK-FIXES: {{^  }}if (!vect2.empty()){{$}}
242 
243   std::vector<int> *vect3 = new std::vector<int>();
244   if (vect3->size() == 0)
245     ;
246   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
247   // CHECK-FIXES: {{^  }}if (vect3->empty()){{$}}
248   if ((*vect3).size() == 0)
249     ;
250   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
251   // CHECK-FIXES: {{^  }}if ((*vect3).empty()){{$}}
252   if ((*vect3) == std::vector<int>())
253     ;
254   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
255   // CHECK-FIXES: {{^  }}if (vect3->empty()){{$}}
256   if (*vect3 == std::vector<int>())
257     ;
258   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
259   // CHECK-FIXES: {{^  }}if (vect3->empty()){{$}}
260 
261   delete vect3;
262 
263   const std::vector<int> &vect4 = vect2;
264   if (vect4.size() == 0)
265     ;
266   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
267   // CHECK-FIXES: {{^  }}if (vect4.empty()){{$}}
268   if (vect4 == std::vector<int>())
269     ;
270   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
271   // CHECK-FIXES: {{^  }}if (vect4.empty()){{$}}
272 
273   TemplatedContainer<void> templated_container;
274   if (templated_container.size() == 0)
275     ;
276   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
277   // CHECK-FIXES: {{^  }}if (templated_container.empty()){{$}}
278   if (templated_container == TemplatedContainer<void>())
279     ;
280   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
281   // CHECK-FIXES: {{^  }}if (templated_container.empty()){{$}}
282   if (templated_container.size() != 0)
283     ;
284   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
285   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
286   if (templated_container != TemplatedContainer<void>())
287     ;
288   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
289   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
290   if (0 == templated_container.size())
291     ;
292   // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
293   // CHECK-FIXES: {{^  }}if (templated_container.empty()){{$}}
294   if (TemplatedContainer<void>() == templated_container)
295     ;
296   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
297   // CHECK-FIXES: {{^  }}if (templated_container.empty()){{$}}
298   if (0 != templated_container.size())
299     ;
300   // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
301   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
302   if (TemplatedContainer<void>() != templated_container)
303     ;
304   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
305   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
306   if (templated_container.size() > 0)
307     ;
308   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
309   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
310   if (0 < templated_container.size())
311     ;
312   // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used
313   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
314   if (templated_container.size() < 1)
315     ;
316   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
317   // CHECK-FIXES: {{^  }}if (templated_container.empty()){{$}}
318   if (1 > templated_container.size())
319     ;
320   // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used
321   // CHECK-FIXES: {{^  }}if (templated_container.empty()){{$}}
322   if (templated_container.size() >= 1)
323     ;
324   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
325   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
326   if (1 <= templated_container.size())
327     ;
328   // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used
329   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
330   if (templated_container.size() > 1) // no warning
331     ;
332   if (1 < templated_container.size()) // no warning
333     ;
334   if (templated_container.size() <= 1) // no warning
335     ;
336   if (1 >= templated_container.size()) // no warning
337     ;
338   if (!templated_container.size())
339     ;
340   // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used
341   // CHECK-FIXES: {{^  }}if (templated_container.empty()){{$}}
342   if (templated_container.size())
343     ;
344   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
345   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
346 
347   if (templated_container.empty())
348     ;
349 
350   // No warnings expected.
351   PrivateEmpty<void> private_empty;
352   if (private_empty.size() == 0)
353     ;
354   if (private_empty == PrivateEmpty<void>())
355     ;
356   if (private_empty.size() != 0)
357     ;
358   if (private_empty != PrivateEmpty<void>())
359     ;
360   if (0 == private_empty.size())
361     ;
362   if (PrivateEmpty<void>() == private_empty)
363     ;
364   if (0 != private_empty.size())
365     ;
366   if (PrivateEmpty<void>() != private_empty)
367     ;
368   if (private_empty.size() > 0)
369     ;
370   if (0 < private_empty.size())
371     ;
372   if (private_empty.size() < 1)
373     ;
374   if (1 > private_empty.size())
375     ;
376   if (private_empty.size() >= 1)
377     ;
378   if (1 <= private_empty.size())
379     ;
380   if (private_empty.size() > 1)
381     ;
382   if (1 < private_empty.size())
383     ;
384   if (private_empty.size() <= 1)
385     ;
386   if (1 >= private_empty.size())
387     ;
388   if (!private_empty.size())
389     ;
390   if (private_empty.size())
391     ;
392 
393   // Types with weird size() return type.
394   BoolSize bs;
395   if (bs.size() == 0)
396     ;
397   EnumSize es;
398   if (es.size() == 0)
399     ;
400 
401   Derived derived;
402   if (derived.size() == 0)
403     ;
404   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
405   // CHECK-FIXES: {{^  }}if (derived.empty()){{$}}
406   if (derived == Derived())
407     ;
408   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
409   // CHECK-FIXES: {{^  }}if (derived.empty()){{$}}
410 
411   takesBool(derived.size());
412   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used
413   // CHECK-FIXES: {{^  }}takesBool(!derived.empty());
414 
415   takesBool(derived.size() == 0);
416   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used
417   // CHECK-FIXES: {{^  }}takesBool(derived.empty());
418 
419   takesBool(derived.size() != 0);
420   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used
421   // CHECK-FIXES: {{^  }}takesBool(!derived.empty());
422 
423   bool b1 = derived.size();
424   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used
425   // CHECK-FIXES: {{^  }}bool b1 = !derived.empty();
426 
427   bool b2(derived.size());
428   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the 'empty' method should be used
429   // CHECK-FIXES: {{^  }}bool b2(!derived.empty());
430 
431   auto b3 = static_cast<bool>(derived.size());
432   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: the 'empty' method should be used
433   // CHECK-FIXES: {{^  }}auto b3 = static_cast<bool>(!derived.empty());
434 
435   auto b4 = (bool)derived.size();
436   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: the 'empty' method should be used
437   // CHECK-FIXES: {{^  }}auto b4 = (bool)!derived.empty();
438 
439   auto b5 = bool(derived.size());
440   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: the 'empty' method should be used
441   // CHECK-FIXES: {{^  }}auto b5 = bool(!derived.empty());
442 
443   return derived.size();
444   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used
445   // CHECK-FIXES: {{^  }}return !derived.empty();
446 }
447 
448 class ConstructWithBoolField {
449   bool B;
450 public:
ConstructWithBoolField(const std::vector<int> & C)451   ConstructWithBoolField(const std::vector<int> &C) : B(C.size()) {}
452 // CHECK-MESSAGES: :[[@LINE-1]]:57: warning: the 'empty' method should be used
453 // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
454 // CHECK-FIXES: {{^  }}ConstructWithBoolField(const std::vector<int> &C) : B(!C.empty()) {}
455 };
456 
457 struct StructWithNSDMI {
458   std::vector<int> C;
459   bool B = C.size();
460 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: the 'empty' method should be used
461 // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
462 // CHECK-FIXES: {{^  }}bool B = !C.empty();
463 };
464 
func(const std::vector<int> & C)465 int func(const std::vector<int> &C) {
466   return C.size() ? 0 : 1;
467 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used
468 // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
469 // CHECK-FIXES: {{^  }}return !C.empty() ? 0 : 1;
470 }
471 
472 constexpr Lazy L;
473 static_assert(!L.size(), "");
474 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: the 'empty' method should be used
475 // CHECK-MESSAGES: :101:18: note: method 'Lazy'::empty() defined here
476 // CHECK-FIXES: {{^}}static_assert(L.empty(), "");
477 
478 struct StructWithLazyNoexcept {
479   void func() noexcept(L.size());
480 };
481 
482 #define CHECKSIZE(x) if (x.size()) {}
483 // CHECK-FIXES: #define CHECKSIZE(x) if (x.size()) {}
484 
f()485 template <typename T> void f() {
486   std::vector<T> v;
487   if (v.size())
488     ;
489   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
490   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
491   // CHECK-FIXES: {{^  }}if (!v.empty()){{$}}
492   if (v == std::vector<T>())
493     ;
494   // 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]
495   // CHECK-FIXES: {{^  }}if (v.empty()){{$}}
496   // CHECK-FIXES-NEXT: ;
497   CHECKSIZE(v);
498   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used
499   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
500   // CHECK-FIXES: CHECKSIZE(v);
501 
502   TemplatedContainer<T> templated_container;
503   if (templated_container.size())
504     ;
505   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
506   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
507   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
508   if (templated_container != TemplatedContainer<T>())
509     ;
510   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
511   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
512   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
513   // CHECK-FIXES-NEXT: ;
514   CHECKSIZE(templated_container);
515   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used
516   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
517   // CHECK-FIXES: CHECKSIZE(templated_container);
518 }
519 
g()520 void g() {
521   f<int>();
522   f<double>();
523   f<char *>();
524 }
525 
526 template <typename T>
neverInstantiatedTemplate()527 bool neverInstantiatedTemplate() {
528   std::vector<T> v;
529   if (v.size())
530     ;
531   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
532   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
533   // CHECK-FIXES: {{^  }}if (!v.empty()){{$}}
534 
535   if (v == std::vector<T>())
536     ;
537   // 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]
538   // CHECK-FIXES: {{^  }}if (v.empty()){{$}}
539   // CHECK-FIXES-NEXT: ;
540   if (v.size() == 0)
541     ;
542   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
543   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
544   // CHECK-FIXES: {{^  }}if (v.empty()){{$}}
545   if (v.size() != 0)
546     ;
547   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
548   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
549   // CHECK-FIXES: {{^  }}if (!v.empty()){{$}}
550   if (v.size() < 1)
551     ;
552   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
553   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
554   // CHECK-FIXES: {{^  }}if (v.empty()){{$}}
555   if (v.size() > 0)
556     ;
557   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
558   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
559   // CHECK-FIXES: {{^  }}if (!v.empty()){{$}}
560   if (v.size() == 1)
561     ;
562   if (v.size() != 1)
563     ;
564   if (v.size() == 2)
565     ;
566   if (v.size() != 2)
567     ;
568 
569   if (static_cast<bool>(v.size()))
570     ;
571   // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
572   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
573   // CHECK-FIXES: {{^  }}if (static_cast<bool>(!v.empty())){{$}}
574   if (v.size() && false)
575     ;
576   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
577   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
578   // CHECK-FIXES: {{^  }}if (!v.empty() && false){{$}}
579   if (!v.size())
580     ;
581   // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
582   // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
583   // CHECK-FIXES: {{^  }}if (v.empty()){{$}}
584 
585   TemplatedContainer<T> templated_container;
586   if (templated_container.size())
587     ;
588   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
589   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
590   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
591   if (templated_container != TemplatedContainer<T>())
592     ;
593   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
594   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
595   // CHECK-FIXES: {{^  }}if (!templated_container.empty()){{$}}
596   // CHECK-FIXES-NEXT: ;
597   while (templated_container.size())
598     ;
599   // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: the 'empty' method should be used
600   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
601   // CHECK-FIXES: {{^  }}while (!templated_container.empty()){{$}}
602 
603   do {
604   }
605   while (templated_container.size());
606   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used
607   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
608   // CHECK-FIXES: {{^  }}while (!templated_container.empty());
609 
610   for (; templated_container.size();)
611     ;
612   // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: the 'empty' method should be used
613   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
614   // CHECK-FIXES: {{^  }}for (; !templated_container.empty();){{$}}
615 
616   if (true && templated_container.size())
617     ;
618   // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: the 'empty' method should be used
619   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
620   // CHECK-FIXES: {{^  }}if (true && !templated_container.empty()){{$}}
621 
622   if (true || templated_container.size())
623     ;
624   // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: the 'empty' method should be used
625   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
626   // CHECK-FIXES: {{^  }}if (true || !templated_container.empty()){{$}}
627 
628   if (!templated_container.size())
629     ;
630   // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used
631   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
632   // CHECK-FIXES: {{^  }}if (templated_container.empty()){{$}}
633 
634   bool b1 = templated_container.size();
635   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used
636   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
637   // CHECK-FIXES: {{^  }}bool b1 = !templated_container.empty();
638 
639   bool b2(templated_container.size());
640   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the 'empty' method should be used
641   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
642   // CHECK-FIXES: {{^  }}bool b2(!templated_container.empty());
643 
644   auto b3 = static_cast<bool>(templated_container.size());
645   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: the 'empty' method should be used
646   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
647   // CHECK-FIXES: {{^  }}auto b3 = static_cast<bool>(!templated_container.empty());
648 
649   auto b4 = (bool)templated_container.size();
650   // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: the 'empty' method should be used
651   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
652   // CHECK-FIXES: {{^  }}auto b4 = (bool)!templated_container.empty();
653 
654   auto b5 = bool(templated_container.size());
655   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: the 'empty' method should be used
656   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
657   // CHECK-FIXES: {{^  }}auto b5 = bool(!templated_container.empty());
658 
659   takesBool(templated_container.size());
660   // We don't detect this one because we don't know the parameter of takesBool
661   // until the type of templated_container.size() is known
662 
663   return templated_container.size();
664   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used
665   // CHECK-MESSAGES: :44:8: note: method 'TemplatedContainer'::empty() defined here
666   // CHECK-FIXES: {{^  }}return !templated_container.empty();
667 }
668 
669 template <typename TypeRequiresSize>
instantiatedTemplateWithSizeCall()670 void instantiatedTemplateWithSizeCall() {
671   TypeRequiresSize t;
672   // The instantiation of the template with std::vector<int> should not
673   // result in changing the template, because we don't know that
674   // TypeRequiresSize generally has `.empty()`
675   if (t.size())
676     ;
677 
678   if (t == TypeRequiresSize{})
679     ;
680 
681   if (t != TypeRequiresSize{})
682     ;
683 }
684 
685 class TypeWithSize {
686 public:
687   TypeWithSize();
688   bool operator==(const TypeWithSize &other) const;
689   bool operator!=(const TypeWithSize &other) const;
690 
size() const691   unsigned size() const { return 0; }
692   // Does not have `.empty()`
693 };
694 
instantiator()695 void instantiator() {
696   instantiatedTemplateWithSizeCall<TypeWithSize>();
697   instantiatedTemplateWithSizeCall<std::vector<int>>();
698 }
699