Index: clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string +++ clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string @@ -26,6 +26,7 @@ const C *data() const; bool empty() const; + size_type size() const; _Type& append(const C *s); _Type& append(const C *s, size_type n); @@ -79,6 +80,10 @@ bool operator!=(const std::string&, const std::string&); bool operator!=(const std::string&, const char*); bool operator!=(const char*, const std::string&); + +bool operator==(const std::wstring&, const std::wstring&); +bool operator==(const std::wstring&, const wchar_t*); +bool operator==(const wchar_t*, const std::wstring&); } #endif // _STRING_ Index: clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp +++ clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp @@ -1,6 +1,7 @@ // RUN: %check_clang_tidy %s readability-container-size-empty %t -- \ // RUN: -config="{CheckOptions: [{key: readability-container-size-empty.ExcludedComparisonTypes , value: '::std::array;::IgnoredDummyType'}]}" \ -// RUN: -- -fno-delayed-template-parsing +// RUN: -- -fno-delayed-template-parsing -isystem %clang_tidy_headers +#include namespace std { template struct vector { @@ -11,20 +12,6 @@ bool empty() const; }; -template struct basic_string { - basic_string(); - bool operator==(const basic_string& other) const; - bool operator!=(const basic_string& other) const; - bool operator==(const char *) const; - bool operator!=(const char *) const; - basic_string operator+(const basic_string& other) const; - unsigned long size() const; - bool empty() const; -}; - -typedef basic_string string; -typedef basic_string wstring; - inline namespace __v2 { template struct set { set(); @@ -125,12 +112,12 @@ ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] // CHECK-FIXES: {{^ }}if (intSet.empty()){{$}} - // CHECK-MESSAGES: :34:8: note: method 'set'::empty() defined here + // CHECK-MESSAGES: :21:8: note: method 'set'::empty() defined here if (intSet == std::set()) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness // CHECK-FIXES: {{^ }}if (intSet.empty()){{$}} - // CHECK-MESSAGES: :34:8: note: method 'set'::empty() defined here + // CHECK-MESSAGES: :21:8: note: method 'set'::empty() defined here if (s_func() == "") ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used @@ -155,7 +142,7 @@ ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used // CHECK-FIXES: {{^ }}if (wstr.empty()){{$}} - if (wstr == "") + if (wstr == L"") ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used // CHECK-FIXES: {{^ }}if (wstr.empty()){{$}} @@ -452,7 +439,7 @@ public: ConstructWithBoolField(const std::vector &C) : B(C.size()) {} // CHECK-MESSAGES: :[[@LINE-1]]:57: warning: the 'empty' method should be used -// CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here +// CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}ConstructWithBoolField(const std::vector &C) : B(!C.empty()) {} }; @@ -460,21 +447,21 @@ std::vector C; bool B = C.size(); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: the 'empty' method should be used -// CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here +// CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}bool B = !C.empty(); }; int func(const std::vector &C) { return C.size() ? 0 : 1; // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used -// CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here +// CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}return !C.empty() ? 0 : 1; } constexpr Lazy L; static_assert(!L.size(), ""); // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: the 'empty' method should be used -// CHECK-MESSAGES: :103:18: note: method 'Lazy'::empty() defined here +// CHECK-MESSAGES: :90:18: note: method 'Lazy'::empty() defined here // CHECK-FIXES: {{^}}static_assert(L.empty(), ""); struct StructWithLazyNoexcept { @@ -489,7 +476,7 @@ if (v.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} if (v == std::vector()) ; @@ -498,24 +485,24 @@ // CHECK-FIXES-NEXT: ; CHECKSIZE(v); // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: CHECKSIZE(v); TemplatedContainer templated_container; if (templated_container.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} if (templated_container != TemplatedContainer()) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} // CHECK-FIXES-NEXT: ; CHECKSIZE(templated_container); // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: CHECKSIZE(templated_container); } @@ -531,7 +518,7 @@ if (v.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} if (v == std::vector()) @@ -542,22 +529,22 @@ if (v.size() == 0) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}if (v.empty()){{$}} if (v.size() != 0) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} if (v.size() < 1) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}if (v.empty()){{$}} if (v.size() > 0) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} if (v.size() == 1) ; @@ -571,91 +558,91 @@ if (static_cast(v.size())) ; // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}if (static_cast(!v.empty())){{$}} if (v.size() && false) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}if (!v.empty() && false){{$}} if (!v.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}if (v.empty()){{$}} TemplatedContainer templated_container; if (templated_container.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} if (templated_container != TemplatedContainer()) ; // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}if (!templated_container.empty()){{$}} // CHECK-FIXES-NEXT: ; while (templated_container.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}while (!templated_container.empty()){{$}} do { } while (templated_container.size()); // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}while (!templated_container.empty()); for (; templated_container.size();) ; // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}for (; !templated_container.empty();){{$}} if (true && templated_container.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}if (true && !templated_container.empty()){{$}} if (true || templated_container.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:15: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}if (true || !templated_container.empty()){{$}} if (!templated_container.size()) ; // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}if (templated_container.empty()){{$}} bool b1 = templated_container.size(); // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}bool b1 = !templated_container.empty(); bool b2(templated_container.size()); // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}bool b2(!templated_container.empty()); auto b3 = static_cast(templated_container.size()); // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}auto b3 = static_cast(!templated_container.empty()); auto b4 = (bool)templated_container.size(); // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}auto b4 = (bool)!templated_container.empty(); auto b5 = bool(templated_container.size()); // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}auto b5 = bool(!templated_container.empty()); takesBool(templated_container.size()); @@ -664,7 +651,7 @@ return templated_container.size(); // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used - // CHECK-MESSAGES: :46:8: note: method 'TemplatedContainer'::empty() defined here + // CHECK-MESSAGES: :33:8: note: method 'TemplatedContainer'::empty() defined here // CHECK-FIXES: {{^ }}return !templated_container.empty(); } @@ -710,14 +697,14 @@ bool call_through_unique_ptr(const std::unique_ptr> &ptr) { return ptr->size() > 0; // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}return !ptr->empty(); } bool call_through_unique_ptr_deref(const std::unique_ptr> &ptr) { return (*ptr).size() > 0; // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used - // CHECK-MESSAGES: :11:8: note: method 'vector'::empty() defined here + // CHECK-MESSAGES: :12:8: note: method 'vector'::empty() defined here // CHECK-FIXES: {{^ }}return !(*ptr).empty(); } @@ -766,7 +753,7 @@ return value.size() == 0U; // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty] // CHECK-FIXES: {{^ }}return value.empty();{{$}} -// CHECK-MESSAGES: :744:8: note: method 'array'::empty() defined here +// CHECK-MESSAGES: :731:8: note: method 'array'::empty() defined here } bool testArrayCompareToEmpty(const Array& value) { @@ -777,7 +764,7 @@ return value == DummyType(); // 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] // CHECK-FIXES: {{^ }}return value.empty();{{$}} -// CHECK-MESSAGES: :754:8: note: method 'DummyType'::empty() defined here +// CHECK-MESSAGES: :741:8: note: method 'DummyType'::empty() defined here } bool testIgnoredDummyType(const IgnoredDummyType& value) {