https://github.com/vbvictor updated 
https://github.com/llvm/llvm-project/pull/190535

>From 5282747199d3c7f867b28206301726cb7d36acf2 Mon Sep 17 00:00:00 2001
From: Victor Baranov <[email protected]>
Date: Mon, 13 Apr 2026 20:46:10 +0300
Subject: [PATCH] fix

---
 .../readability/ContainerSizeEmptyCheck.cpp   | 28 ++++---
 clang-tools-extra/docs/ReleaseNotes.rst       |  3 +
 .../readability/container-size-empty.cpp      | 74 +++++++++++++++++++
 3 files changed, 96 insertions(+), 9 deletions(-)

diff --git 
a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
index 2101fd2248e8a..cbad3d244d841 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
@@ -144,15 +144,18 @@ void 
ContainerSizeEmptyCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
 }
 
 void ContainerSizeEmptyCheck::registerMatchers(MatchFinder *Finder) {
-  const auto ValidContainerRecord = 
cxxRecordDecl(isSameOrDerivedFrom(namedDecl(
-      has(cxxMethodDecl(
-              isConst(), parameterCountIs(0), isPublic(),
-              hasAnyName("size", "length"),
-              returns(qualType(isIntegralType(), unless(booleanType()))))
-              .bind("size")),
-      has(cxxMethodDecl(isConst(), parameterCountIs(0), isPublic(),
-                        hasName("empty"), returns(booleanType()))
-              .bind("empty")))));
+  const auto ValidContainerRecord =
+      cxxRecordDecl(
+          isSameOrDerivedFrom(namedDecl(
+              has(cxxMethodDecl(isConst(), parameterCountIs(0), isPublic(),
+                                hasAnyName("size", "length"),
+                                returns(qualType(isIntegralType(),
+                                                 unless(booleanType()))))
+                      .bind("size")),
+              has(cxxMethodDecl(isConst(), parameterCountIs(0), isPublic(),
+                                hasName("empty"), returns(booleanType()))
+                      .bind("empty")))))
+          .bind("ContainerDecl");
 
   const auto ValidContainerNonTemplateType =
       qualType(hasUnqualifiedDesugaredType(
@@ -235,6 +238,13 @@ void ContainerSizeEmptyCheck::registerMatchers(MatchFinder 
*Finder) {
   Finder->addMatcher(
       binaryOperation(
           hasAnyOperatorName("==", "!="), hasOperands(WrongComparend, STLArg),
+          unless(hasEitherOperand(cxxConstructExpr(
+              argumentCountIs(0),
+              unless(hasType(qualType(hasCanonicalType(hasDeclaration(
+                  // 'equalsBoundNode' needs the 'ContainerDecl' binding
+                  // from 'STLArg' to already exist, so this constraint must
+                  // appear after 'hasOperands' matcher
+                  namedDecl(equalsBoundNode("ContainerDecl")))))))))),
           unless(allOf(hasLHS(hasType(ExcludedComparisonTypesMatcher)),
                        hasRHS(hasType(SameExcludedComparisonTypesMatcher)))),
           NotInEmptyMethodOfContainer)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 69dc5b9633398..565e0dfedb971 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -399,6 +399,9 @@ Changes in existing checks
   - Reduce verbosity by removing the note indicating source location of the
     ``empty`` function.
 
+  - Fixed a false positive with suggesting ``empty`` when comparing a container
+    to a default-constructed object of an unrelated type.
+
 - Improved :doc:`readability-else-after-return
   <clang-tidy/checks/readability/else-after-return>` check:
 
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp
index 2b8b3261ac765..cd2eebb16138b 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/container-size-empty.cpp
@@ -954,3 +954,77 @@ struct DestructorUser {
   }
 };
 }
+
+namespace GH162287 {
+
+struct Label {
+  virtual ~Label();
+};
+bool operator==(std::string, const Label&);
+bool operator==(std::string, std::vector<char>);
+bool operator==(const Label&, std::string);
+
+void testUnrelatedType() {
+  std::string s{"aa"};
+  if (s == Label{})
+    ;
+  if (s == Label())
+    ;
+  if (s == std::vector<char>{})
+    ;
+  if (Label() == s)
+    ;
+}
+
+void testValid() {
+  std::string s{"aa"};
+  std::vector<int> v;
+  Container c;
+
+  // CHECK-MESSAGES: :[[@LINE+2]]:7: warning: the 'empty' method should be 
used to check for emptiness instead of comparing to an empty object
+  // CHECK-FIXES:  if (s.empty())
+  if (s == std::string{})
+    ;
+  // CHECK-MESSAGES: :[[@LINE+2]]:7: warning: the 'empty' method should be 
used to check for emptiness instead of comparing to an empty object
+  // CHECK-FIXES:  if (s.empty())
+  if (std::string() == s)
+    ;
+  // CHECK-MESSAGES: :[[@LINE+2]]:7: warning: the 'empty' method should be 
used to check for emptiness instead of comparing to an empty object
+  // CHECK-FIXES:  if (c.empty())
+  if (c == Container())
+    ;
+  Container *p = nullptr;
+  // CHECK-MESSAGES: :[[@LINE+2]]:7: warning: the 'empty' method should be 
used to check for emptiness instead of comparing to an empty object
+  // CHECK-FIXES:  if (p->empty())
+  if (*p == Container())
+    ;
+  using MyString = std::string;
+  MyString ms{"aa"};
+  // CHECK-MESSAGES: :[[@LINE+2]]:7: warning: the 'empty' method should be 
used to check for emptiness instead of comparing to an empty object
+  // CHECK-FIXES:  if (ms.empty())
+  if (ms == std::string())
+    ;
+  bool b1 = s == Label();
+  // CHECK-MESSAGES: :[[@LINE+2]]:13: warning: the 'empty' method should be 
used to check for emptiness instead of comparing to an empty object
+  // CHECK-FIXES:  bool b2 = c.empty();
+  bool b2 = c == Container();
+  // CHECK-MESSAGES: :[[@LINE+2]]:7: warning: the 'empty' method should be 
used to check for emptiness instead of comparing to an empty object
+  // CHECK-FIXES:  if (v.empty())
+  if (v == std::vector<int>())
+    ;
+}
+
+template <typename T>
+bool testUnrelatedInTemplate(std::string s) {
+  return s == Label{};
+}
+template bool testUnrelatedInTemplate<int>(std::string);
+
+template <typename T>
+bool testDependentValidContainer(TemplatedContainer<T> c) {
+  return c == TemplatedContainer<T>();
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be 
used to check for emptiness instead of comparing to an empty object
+  // CHECK-FIXES:  return c.empty();
+}
+template bool testDependentValidContainer<int>(TemplatedContainer<int>);
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to