[clang-tools-extra] [clang-tidy] Ignore implicit functions in readability-implicit-bool-conversion (PR #94512)

Piotr Zegar via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 5 11:16:52 PDT 2024


https://github.com/PiotrZSL created https://github.com/llvm/llvm-project/pull/94512

Ignore implicit declarations and defaulted functions. Helps with issues in generated code like, C++
spaceship operator.

Closes #93409

>From 22cd99f5288f53eb561a3040ce78c5143a9a7dad Mon Sep 17 00:00:00 2001
From: Piotr Zegar <me at piotrzegar.pl>
Date: Wed, 5 Jun 2024 17:40:18 +0000
Subject: [PATCH] [clang-tidy] Ignore implicit functions in
 readability-implicit-bool-conversion

Ignore implicit declarations and defaulted functions.
Helps with issues in generated code like, C++
spaceship operator.

Closes #93409
---
 .../ImplicitBoolConversionCheck.cpp           |  7 +++--
 clang-tools-extra/docs/ReleaseNotes.rst       |  3 +-
 .../implicit-bool-conversion-cxx20.cpp        | 31 +++++++++++++++++++
 3 files changed, 38 insertions(+), 3 deletions(-)
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx20.cpp

diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
index 28f5eada6d825..aa115cd450c4f 100644
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
@@ -279,6 +279,9 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
       hasParent(callExpr()),
       hasSourceExpression(binaryOperator(hasAnyOperatorName("==", "!="))));
 
+  auto IsInCompilerGeneratedFunction = hasAncestor(namedDecl(anyOf(
+      isImplicit(), functionDecl(isDefaulted()), functionTemplateDecl())));
+
   Finder->addMatcher(
       traverse(TK_AsIs,
                implicitCastExpr(
@@ -299,7 +302,7 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
                    // additional parens in replacement.
                    optionally(hasParent(stmt().bind("parentStmt"))),
                    unless(isInTemplateInstantiation()),
-                   unless(hasAncestor(functionTemplateDecl())))
+                   unless(IsInCompilerGeneratedFunction))
                    .bind("implicitCastToBool")),
       this);
 
@@ -331,7 +334,7 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
               anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")),
                     anything()),
               unless(isInTemplateInstantiation()),
-              unless(hasAncestor(functionTemplateDecl())))),
+              unless(IsInCompilerGeneratedFunction))),
       this);
 }
 
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 33b65caf2b02c..6e2344de3e09f 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -397,7 +397,8 @@ Changes in existing checks
   valid fix suggestions for ``static_cast`` without a preceding space and
   fixed problem with duplicate parentheses in double implicit casts. Corrected
   the fix suggestions for C23 and later by using C-style casts instead of
-  ``static_cast``.
+  ``static_cast``. Fixed false positives in C++20 spaceship operator by ignoring
+  casts in implicit and defaulted functions.
 
 - Improved :doc:`readability-redundant-inline-specifier
   <clang-tidy/checks/readability/redundant-inline-specifier>` check to properly
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx20.cpp
new file mode 100644
index 0000000000000..13aa5c5774b47
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-cxx20.cpp
@@ -0,0 +1,31 @@
+// RUN: %check_clang_tidy -std=c++20 %s readability-implicit-bool-conversion %t
+
+namespace std {
+struct strong_ordering {
+  int n;
+  constexpr operator int() const { return n; }
+  static const strong_ordering equal, greater, less;
+};
+constexpr strong_ordering strong_ordering::equal = {0};
+constexpr strong_ordering strong_ordering::greater = {1};
+constexpr strong_ordering strong_ordering::less = {-1};
+} // namespace std
+
+namespace PR93409 {
+  struct X
+  {
+      auto operator<=>(const X&) const = default;
+      bool m_b;
+  };
+
+  struct Y
+  {
+      auto operator<=>(const Y&) const = default;
+      X m_x;
+  };
+  
+  bool compare(const Y& y1, const Y& y2)
+  {
+     return y1 == y2 || y1 < y2 || y1 > y2;
+  }
+}



More information about the cfe-commits mailing list