988 lines · cpp
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_headers4#include <string>5 6namespace std {7template <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 15inline namespace __v2 {16template <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 25namespace string_literals{26string operator""s(const char *, size_t);27}28 29}30 31template <typename T>32class TemplatedContainer {33public: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 40template <typename T>41class PrivateEmpty {42public:43 bool operator==(const PrivateEmpty<T>& other) const;44 bool operator!=(const PrivateEmpty<T>& other) const;45 unsigned long size() const;46private:47 bool empty() const;48};49 50struct BoolSize {51 bool size() const;52 bool empty() const;53};54 55struct EnumSize {56 enum E { one };57 enum E size() const;58 bool empty() const;59};60 61class Container {62public:63 bool operator==(const Container& other) const;64 unsigned long size() const;65 bool empty() const;66};67 68class Derived : public Container {69};70 71class Container2 {72public:73 unsigned long size() const;74 bool empty() const { return size() == 0; }75};76 77class Container3 {78public:79 unsigned long size() const;80 bool empty() const;81};82 83bool Container3::empty() const { return this->size() == 0; }84 85class Container4 {86public:87 bool operator==(const Container4& rhs) const;88 unsigned long size() const;89 bool empty() const { return *this == Container4(); }90};91 92struct Lazy {93 constexpr unsigned size() const { return 0; }94 constexpr bool empty() const { return true; }95};96 97std::string s_func() {98 return std::string();99}100 101void takesBool(bool)102{103 104}105 106bool 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 here124 if (intSet == std::set<int>())125 ;126 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness127 // CHECK-FIXES: if (intSet.empty())128 // CHECK-MESSAGES: :21:8: note: method 'set'::empty() defined here129 if (s_func() == "")130 ;131 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used132 // 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 used152 // CHECK-FIXES: if (str.empty())153 if (str + str2 == "")154 ;155 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used156 // 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 used168 // 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 used177 // CHECK-FIXES: if (vect.empty())178 if (vect.size() != 0)179 ;180 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used181 // CHECK-FIXES: if (!vect.empty())182 if (vect != std::vector<int>())183 ;184 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used185 // CHECK-FIXES: if (!vect.empty())186 if (0 == vect.size())187 ;188 // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used189 // CHECK-FIXES: if (vect.empty())190 if (0 != vect.size())191 ;192 // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used193 // CHECK-FIXES: if (!vect.empty())194 if (std::vector<int>() == vect)195 ;196 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used197 // CHECK-FIXES: if (vect.empty())198 if (std::vector<int>() != vect)199 ;200 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used201 // CHECK-FIXES: if (!vect.empty())202 if (vect.size() > 0)203 ;204 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used205 // CHECK-FIXES: if (!vect.empty())206 if (0 < vect.size())207 ;208 // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used209 // CHECK-FIXES: if (!vect.empty())210 if (vect.size() < 1)211 ;212 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used213 // CHECK-FIXES: if (vect.empty())214 if (1 > vect.size())215 ;216 // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: the 'empty' method should be used217 // CHECK-FIXES: if (vect.empty())218 if (vect.size() >= 1)219 ;220 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used221 // CHECK-FIXES: if (!vect.empty())222 if (1 <= vect.size())223 ;224 // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should be used225 // CHECK-FIXES: if (!vect.empty())226 if (vect.size() > 1) // no warning227 ;228 if (1 < vect.size()) // no warning229 ;230 if (vect.size() <= 1) // no warning231 ;232 if (1 >= vect.size()) // no warning233 ;234 if (!vect.size())235 ;236 // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used237 // CHECK-FIXES: if (vect.empty())238 if (vect.size())239 ;240 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used241 // 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 used250 // 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 used256 // CHECK-FIXES: if (vect3->empty())257 if ((*vect3).size() == 0)258 ;259 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used260 // CHECK-FIXES: if ((*vect3).empty())261 if ((*vect3) == std::vector<int>())262 ;263 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used264 // CHECK-FIXES: if (vect3->empty())265 if (*vect3 == std::vector<int>())266 ;267 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used268 // 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 used276 // CHECK-FIXES: if (vect4.empty())277 if (vect4 == std::vector<int>())278 ;279 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used280 // 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 used286 // 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 used290 // 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 used294 // 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 used298 // 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 used302 // 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 used306 // 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 used310 // 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 used314 // 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 used318 // 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 used322 // 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 used326 // 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 used330 // 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 used334 // 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 used338 // CHECK-FIXES: if (!templated_container.empty())339 if (templated_container.size() > 1) // no warning340 ;341 if (1 < templated_container.size()) // no warning342 ;343 if (templated_container.size() <= 1) // no warning344 ;345 if (1 >= templated_container.size()) // no warning346 ;347 if (!templated_container.size())348 ;349 // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used350 // CHECK-FIXES: if (templated_container.empty())351 if (templated_container.size())352 ;353 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used354 // 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 used414 // CHECK-FIXES: if (derived.empty())415 if (derived == Derived())416 ;417 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used418 // CHECK-FIXES: if (derived.empty())419 420 takesBool(derived.size());421 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used422 // CHECK-FIXES: takesBool(!derived.empty());423 424 takesBool(derived.size() == 0);425 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used426 // CHECK-FIXES: takesBool(derived.empty());427 428 takesBool(derived.size() != 0);429 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used430 // CHECK-FIXES: takesBool(!derived.empty());431 432 bool b1 = derived.size();433 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used434 // CHECK-FIXES: bool b1 = !derived.empty();435 436 bool b2(derived.size());437 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the 'empty' method should be used438 // 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 used442 // 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 used446 // 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 used450 // CHECK-FIXES: auto b5 = bool(!derived.empty());451 452 return derived.size();453 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used454 // CHECK-FIXES: return !derived.empty();455}456 457class ConstructWithBoolField {458 bool B;459public:460 ConstructWithBoolField(const std::vector<int> &C) : B(C.size()) {}461// CHECK-MESSAGES: :[[@LINE-1]]:57: warning: the 'empty' method should be used462// CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here463// CHECK-FIXES: ConstructWithBoolField(const std::vector<int> &C) : B(!C.empty()) {}464};465 466struct StructWithNSDMI {467 std::vector<int> C;468 bool B = C.size();469// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: the 'empty' method should be used470// CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here471// CHECK-FIXES: bool B = !C.empty();472};473 474int func(const std::vector<int> &C) {475 return C.size() ? 0 : 1;476// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used477// CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here478// CHECK-FIXES: return !C.empty() ? 0 : 1;479}480 481constexpr Lazy L;482static_assert(!L.size(), "");483// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: the 'empty' method should be used484// CHECK-MESSAGES: :94:18: note: method 'Lazy'::empty() defined here485// CHECK-FIXES: static_assert(L.empty(), "");486 487struct 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 494template <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 here500 // 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 used508 // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here509 // 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 used515 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here516 // 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 used520 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here521 // 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 used525 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here526 // 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 here532 // 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 here537 // CHECK-FIXES: if (!s.empty())538}539 540void g() {541 f<int>();542 f<double>();543 f<char *>();544}545 546template <typename T>547bool 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 here553 // 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 here564 // 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 here569 // 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 here574 // 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 here579 // 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 here593 // 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 here598 // 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 here603 // 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 used609 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here610 // 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 used614 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here615 // 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 used620 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here621 // 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 used627 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here628 // 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 used633 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here634 // 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 used639 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here640 // 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 used645 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here646 // 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 used651 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here652 // 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 used656 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here657 // 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 used661 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here662 // 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 used666 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here667 // 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 used671 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here672 // 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 used676 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here677 // 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 takesBool681 // until the type of templated_container.size() is known682 683 return templated_container.size();684 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used685 // CHECK-MESSAGES: :37:8: note: method 'TemplatedContainer'::empty() defined here686 // CHECK-FIXES: return !templated_container.empty();687}688 689template <typename TypeRequiresSize>690void instantiatedTemplateWithSizeCall() {691 TypeRequiresSize t;692 // The instantiation of the template with std::vector<int> should not693 // result in changing the template, because we don't know that694 // TypeRequiresSize generally has `.empty()`695 if (t.size())696 ;697 698 if (t == TypeRequiresSize{})699 ;700 701 if (t != TypeRequiresSize{})702 ;703}704 705class TypeWithSize {706public: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 715void instantiator() {716 instantiatedTemplateWithSizeCall<TypeWithSize>();717 instantiatedTemplateWithSizeCall<std::vector<int>>();718}719 720namespace std {721template <typename T>722struct unique_ptr {723 T *operator->() const;724 T &operator*() const;725};726} // namespace std727 728bool 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 used731 // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here732 // CHECK-FIXES: return !ptr->empty();733}734 735bool 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 used738 // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here739 // CHECK-FIXES: return !(*ptr).empty();740}741 742struct TypedefSize {743 typedef int size_type;744 size_type size() const;745 bool empty() const;746};747 748void testTypedefSize() {749 TypedefSize ts;750 if (ts.size() == 0)751 ;752 // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used753 // CHECK-FIXES: if (ts.empty())754}755 756namespace std {757 758template <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 769struct DummyType {770 bool operator==(const DummyType&) const;771 unsigned long size() const;772 bool empty() const;773};774 775struct IgnoredDummyType {776 bool operator==(const IgnoredDummyType&) const;777 unsigned long size() const;778 bool empty() const;779};780 781typedef std::array<int, 10U> Array;782 783bool 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 here788}789 790bool testArrayCompareToEmpty(const Array& value) {791 return value == std::array<int, 10U>();792}793 794bool 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 here799}800 801bool testIgnoredDummyType(const IgnoredDummyType& value) {802 return value == IgnoredDummyType();803}804 805bool 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 used810 // CHECK-FIXES: return s.empty();811}812 813bool testNotEmptyStringLiterals(const std::string& s)814{815 using namespace std::string_literals;816 return s == "foo"s;817}818 819namespace 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 865namespace PR88203 {866 struct SS {867 bool empty() const;868 int size() const;869 int length(int) const;870 };871 872 struct SU {873 bool empty() const;874 int size(int) const;875 int length() const;876 };877 878 void f(const SS& s) {879 if (0 == s.length(1)) {}880 if (0 == s.size()) {}881 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]882 // CHECK-FIXES: if (s.empty()) {}883 }884 885 void f(const SU& s) {886 if (0 == s.size(1)) {}887 if (0 == s.length()) {}888 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: the 'empty' method should be used to check for emptiness instead of 'length' [readability-container-size-empty]889 // CHECK-FIXES: if (s.empty()) {}890 }891}892 893namespace PR94454 {894 template <char...>895 int operator""_ci() { return 0; }896 auto eq = 0_ci == 0;897}898 899namespace GH152387 {900 901class foo : public std::string{902 void doit() {903 if (!size()) {904 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used to check for emptiness instead of 'size'905 // CHECK-FIXES: if (empty()) {906 }907 }908};909 910}911 912namespace GH154762 {913class TypeRange {914 std::vector<int> b;915 916public:917 TypeRange(std::vector<int> b = {});918 TypeRange(int);919 bool operator==(const TypeRange& other) const;920 921 size_t size() const {922 return b.size();923 }924 925 bool empty() const {926 return size() == 0;927 }928};929 930void foo(std::vector<int> v) {931 if (TypeRange(1) == TypeRange(v)) { // no warning932 }933 934 if (TypeRange(1) == TypeRange()) {935 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: the 'empty' method should be used to check for emptiness instead of comparing to an empty object936 // CHECK-FIXES: if (TypeRange(1).empty()) {937 }938 939 if (TypeRange(v) == TypeRange()) {940 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: the 'empty' method should be used to check for emptiness instead of comparing to an empty object941 // CHECK-FIXES: if (TypeRange(v).empty()) {942 }943}944}945 946class ReportInContainerNonEmptyMethod {947public:948 int size() const;949 bool empty() const;950 951 void doit() {952 if (!size()) {953 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used to check for emptiness instead of 'size'954 // CHECK-FIXES: if (empty()) {955 }956 }957};958 959template <typename T>960class ReportInTemplateContainerNonEmptyMethod {961public:962 int size() const;963 bool empty() const;964 965 void doit() {966 if (!size()) {967 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used to check for emptiness instead of 'size'968 // CHECK-FIXES: if (empty()) {969 }970 }971};972 973 974 975class ReportInContainerNonEmptyMethodCompare {976public:977 bool operator==(const ReportInContainerNonEmptyMethodCompare& other) const;978 int size() const;979 bool empty() const;980 981 void doit() {982 if (*this == ReportInContainerNonEmptyMethodCompare()) {983 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: the 'empty' method should be used to check for emptiness instead of comparing to an empty object984 // CHECK-FIXES: if (this->empty()) {985 }986 }987};988