[clang-tools-extra] [clang-tidy] Consider `readability-uppercase-literal-suffix` when dealing with `readability-implicit-bool-conversion`. (PR #104694)

via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 17 23:19:30 PDT 2024


https://github.com/c8ef created https://github.com/llvm/llvm-project/pull/104694

None

>From 5e2cd3fa3ce2676e4d528bd8c1342af138cca604 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 18 Aug 2024 06:17:32 +0000
Subject: [PATCH] [clang-tidy] readability-implicit-bool-conversion take
 readability-uppercase-literal-suffix into account

---
 .../ImplicitBoolConversionCheck.cpp           | 36 ++++++++++++++-----
 .../readability/ImplicitBoolConversionCheck.h |  1 +
 .../implicit-bool-conversion-uppercase.cpp    | 21 +++++++++++
 3 files changed, 49 insertions(+), 9 deletions(-)
 create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-uppercase.cpp

diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
index aa115cd450c4f6..3bd0b5530a9a5a 100644
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
@@ -40,13 +40,18 @@ AST_MATCHER(Stmt, isNULLMacroExpansion) {
 
 StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind,
                                              QualType Type,
+                                             bool IsUseUppercaseSuffixEnabled,
                                              ASTContext &Context) {
   switch (CastExprKind) {
   case CK_IntegralToBoolean:
-    return Type->isUnsignedIntegerType() ? "0u" : "0";
+    return Type->isUnsignedIntegerType()
+               ? (IsUseUppercaseSuffixEnabled ? "0U" : "0u")
+               : "0";
 
   case CK_FloatingToBoolean:
-    return Context.hasSameType(Type, Context.FloatTy) ? "0.0f" : "0.0";
+    return Context.hasSameType(Type, Context.FloatTy)
+               ? (IsUseUppercaseSuffixEnabled ? "0.0F" : "0.0f")
+               : "0.0";
 
   case CK_PointerToBoolean:
   case CK_MemberPointerToBoolean: // Fall-through on purpose.
@@ -66,6 +71,7 @@ bool isUnaryLogicalNotOperator(const Stmt *Statement) {
 
 void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
                               const ImplicitCastExpr *Cast, const Stmt *Parent,
+                              bool IsUseUppercaseSuffixEnabled,
                               ASTContext &Context) {
   // In case of expressions like (! integer), we should remove the redundant not
   // operator and use inverted comparison (integer == 0).
@@ -113,7 +119,8 @@ void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
   }
 
   EndLocInsertion += getZeroLiteralToCompareWithForType(
-      Cast->getCastKind(), SubExpr->getType(), Context);
+      Cast->getCastKind(), SubExpr->getType(), IsUseUppercaseSuffixEnabled,
+      Context);
 
   if (NeedOuterParens) {
     EndLocInsertion += ")";
@@ -192,7 +199,9 @@ void fixGenericExprCastFromBool(DiagnosticBuilder &Diag,
 }
 
 StringRef getEquivalentForBoolLiteral(const CXXBoolLiteralExpr *BoolLiteral,
-                                      QualType DestType, ASTContext &Context) {
+                                      QualType DestType,
+                                      bool IsUseUppercaseSuffixEnabled,
+                                      ASTContext &Context) {
   // Prior to C++11, false literal could be implicitly converted to pointer.
   if (!Context.getLangOpts().CPlusPlus11 &&
       (DestType->isPointerType() || DestType->isMemberPointerType()) &&
@@ -202,13 +211,17 @@ StringRef getEquivalentForBoolLiteral(const CXXBoolLiteralExpr *BoolLiteral,
 
   if (DestType->isFloatingType()) {
     if (Context.hasSameType(DestType, Context.FloatTy)) {
-      return BoolLiteral->getValue() ? "1.0f" : "0.0f";
+      return BoolLiteral->getValue()
+                 ? (IsUseUppercaseSuffixEnabled ? "1.0F" : "1.0f")
+                 : (IsUseUppercaseSuffixEnabled ? "0.0F" : "0.0f");
     }
     return BoolLiteral->getValue() ? "1.0" : "0.0";
   }
 
   if (DestType->isUnsignedIntegerType()) {
-    return BoolLiteral->getValue() ? "1u" : "0u";
+    return BoolLiteral->getValue()
+               ? (IsUseUppercaseSuffixEnabled ? "1U" : "1u")
+               : (IsUseUppercaseSuffixEnabled ? "0U" : "0u");
   }
   return BoolLiteral->getValue() ? "1" : "0";
 }
@@ -248,7 +261,9 @@ ImplicitBoolConversionCheck::ImplicitBoolConversionCheck(
     StringRef Name, ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
       AllowIntegerConditions(Options.get("AllowIntegerConditions", false)),
-      AllowPointerConditions(Options.get("AllowPointerConditions", false)) {}
+      AllowPointerConditions(Options.get("AllowPointerConditions", false)),
+      IsUseUppercaseSuffixEnabled(
+          Context->isCheckEnabled("readability-uppercase-literal-suffix")) {}
 
 void ImplicitBoolConversionCheck::storeOptions(
     ClangTidyOptions::OptionMap &Opts) {
@@ -378,7 +393,8 @@ void ImplicitBoolConversionCheck::handleCastToBool(const ImplicitCastExpr *Cast,
   if (!EquivalentLiteral.empty()) {
     Diag << tooling::fixit::createReplacement(*Cast, EquivalentLiteral);
   } else {
-    fixGenericExprCastToBool(Diag, Cast, Parent, Context);
+    fixGenericExprCastToBool(Diag, Cast, Parent, IsUseUppercaseSuffixEnabled,
+                             Context);
   }
 }
 
@@ -393,7 +409,9 @@ void ImplicitBoolConversionCheck::handleCastFromBool(
   if (const auto *BoolLiteral =
           dyn_cast<CXXBoolLiteralExpr>(Cast->getSubExpr()->IgnoreParens())) {
     Diag << tooling::fixit::createReplacement(
-        *Cast, getEquivalentForBoolLiteral(BoolLiteral, DestType, Context));
+        *Cast,
+        getEquivalentForBoolLiteral(BoolLiteral, DestType,
+                                    IsUseUppercaseSuffixEnabled, Context));
   } else {
     fixGenericExprCastFromBool(Diag, Cast, Context, DestType.getAsString());
   }
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
index 9defec91e2f78d..9bdd7946d4fc43 100644
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
@@ -36,6 +36,7 @@ class ImplicitBoolConversionCheck : public ClangTidyCheck {
 
   const bool AllowIntegerConditions;
   const bool AllowPointerConditions;
+  const bool IsUseUppercaseSuffixEnabled;
 };
 
 } // namespace clang::tidy::readability
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-uppercase.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-uppercase.cpp
new file mode 100644
index 00000000000000..0ccf8d259a49b1
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-uppercase.cpp
@@ -0,0 +1,21 @@
+// RUN: %check_clang_tidy %s readability-implicit-bool-conversion,readability-uppercase-literal-suffix %t
+
+bool implicitConversionToBoolInReturnValue() {
+  float floating = 1.0F;
+  return floating;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool'
+  // CHECK-FIXES: return floating != 0.0F;
+}
+
+void functionTakingUnsignedLong(unsigned long);
+void functionTakingFloat(float);
+
+void implicitConversionFromBoolLiterals() {
+  functionTakingUnsignedLong(false);
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'bool' -> 'unsigned long'
+  // CHECK-FIXES: functionTakingUnsignedLong(0U);
+
+  functionTakingFloat(false);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'float'
+  // CHECK-FIXES: functionTakingFloat(0.0F);
+}



More information about the cfe-commits mailing list