[clang-tools-extra] b45527d - [clang-tidy] Add UseUpperCaseLiteralSuffix option to readability-implicit-bool-conversion (#104882)

via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 27 00:24:51 PDT 2024


Author: Da-Viper
Date: 2024-08-27T09:24:48+02:00
New Revision: b45527da23ed64a503cc0fd18f63692eb3589748

URL: https://github.com/llvm/llvm-project/commit/b45527da23ed64a503cc0fd18f63692eb3589748
DIFF: https://github.com/llvm/llvm-project/commit/b45527da23ed64a503cc0fd18f63692eb3589748.diff

LOG: [clang-tidy] Add UseUpperCaseLiteralSuffix option to readability-implicit-bool-conversion (#104882)

When readability-implicit-bool-conversion-check and
readability-uppercase-literal-suffix-check is enabled this will cause
you to apply a fix twice

from (!i) -> (i == 0u) to (i == 0U) twice instead will skip the middle
one

Adding this option allows this check to be in sync with readability-uppercase-literal-suffix, avoiding duplicate warnings.

Fixes #40544

Added: 
    

Modified: 
    clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
    clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
    clang-tools-extra/docs/ReleaseNotes.rst
    clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst
    clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c
    clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
index aa115cd450c4f6..968a4a55a6d798 100644
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
@@ -66,7 +66,8 @@ bool isUnaryLogicalNotOperator(const Stmt *Statement) {
 
 void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
                               const ImplicitCastExpr *Cast, const Stmt *Parent,
-                              ASTContext &Context) {
+                              ASTContext &Context,
+                              bool UseUpperCaseLiteralSuffix) {
   // In case of expressions like (! integer), we should remove the redundant not
   // operator and use inverted comparison (integer == 0).
   bool InvertComparison =
@@ -112,9 +113,14 @@ void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
     EndLocInsertion += " != ";
   }
 
-  EndLocInsertion += getZeroLiteralToCompareWithForType(
+  const StringRef ZeroLiteral = getZeroLiteralToCompareWithForType(
       Cast->getCastKind(), SubExpr->getType(), Context);
 
+  if (UseUpperCaseLiteralSuffix)
+    EndLocInsertion += ZeroLiteral.upper();
+  else
+    EndLocInsertion += ZeroLiteral;
+
   if (NeedOuterParens) {
     EndLocInsertion += ")";
   }
@@ -248,12 +254,15 @@ ImplicitBoolConversionCheck::ImplicitBoolConversionCheck(
     StringRef Name, ClangTidyContext *Context)
     : ClangTidyCheck(Name, Context),
       AllowIntegerConditions(Options.get("AllowIntegerConditions", false)),
-      AllowPointerConditions(Options.get("AllowPointerConditions", false)) {}
+      AllowPointerConditions(Options.get("AllowPointerConditions", false)),
+      UseUpperCaseLiteralSuffix(
+          Options.get("UseUpperCaseLiteralSuffix", false)) {}
 
 void ImplicitBoolConversionCheck::storeOptions(
     ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "AllowIntegerConditions", AllowIntegerConditions);
   Options.store(Opts, "AllowPointerConditions", AllowPointerConditions);
+  Options.store(Opts, "UseUpperCaseLiteralSuffix", UseUpperCaseLiteralSuffix);
 }
 
 void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
@@ -378,7 +387,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, Context,
+                             UseUpperCaseLiteralSuffix);
   }
 }
 
@@ -392,8 +402,16 @@ void ImplicitBoolConversionCheck::handleCastFromBool(
 
   if (const auto *BoolLiteral =
           dyn_cast<CXXBoolLiteralExpr>(Cast->getSubExpr()->IgnoreParens())) {
-    Diag << tooling::fixit::createReplacement(
-        *Cast, getEquivalentForBoolLiteral(BoolLiteral, DestType, Context));
+
+    const auto EquivalentForBoolLiteral =
+        getEquivalentForBoolLiteral(BoolLiteral, DestType, Context);
+    if (UseUpperCaseLiteralSuffix)
+      Diag << tooling::fixit::createReplacement(
+          *Cast, EquivalentForBoolLiteral.upper());
+    else
+      Diag << tooling::fixit::createReplacement(*Cast,
+                                                EquivalentForBoolLiteral);
+
   } 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..5947f7316e67cc 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 UseUpperCaseLiteralSuffix;
 };
 
 } // namespace clang::tidy::readability

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 1b025e8f90f7ba..b001a6ad446695 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -112,6 +112,11 @@ Changes in existing checks
   <clang-tidy/checks/modernize/use-std-print>` check to support replacing
   member function calls too.
 
+- Improved :doc:`readablility-implicit-bool-conversion
+  <clang-tidy/checks/readability/implicit-bool-conversion>` check
+  by adding the option `UseUpperCaseLiteralSuffix` to select the
+  case of the literal suffix in fixes.
+
 - Improved :doc:`readability-redundant-smartptr-get
   <clang-tidy/checks/readability/redundant-smartptr-get>` check to
   remove `->`, when redundant `get()` is removed.

diff  --git a/clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst
index 1ab21ffeb42289..88cff387f4c165 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/implicit-bool-conversion.rst
@@ -133,3 +133,17 @@ Options
 
    When `true`, the check will allow conditional pointer conversions. Default
    is `false`.
+
+.. option::  UseUpperCaseLiteralSuffix
+
+   When `true`, the replacements will use an uppercase literal suffix in the
+   provided fixes. Default is `false`.
+
+    Example
+
+    .. code-block:: c++
+
+      uint32_t foo;
+      if (foo) {}
+      // ^ propose replacement default: if (foo != 0u) {}
+      // ^ propose replacement with option `UseUpperCaseLiteralSuffix`: if (foo != 0U) {}

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c
index a8c69858f76b61..f3dc32c10d640a 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.c
@@ -1,4 +1,8 @@
 // RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t -- -- -std=c23
+// RUN: %check_clang_tidy -check-suffix=UPPER-CASE %s readability-implicit-bool-conversion %t -- \
+// RUN:     -config='{CheckOptions: { \
+// RUN:         readability-implicit-bool-conversion.UseUpperCaseLiteralSuffix: true \
+// RUN:     }}' -- -std=c23
 
 #undef NULL
 #define NULL 0L
@@ -95,6 +99,7 @@ void implicitConversionFromBoolLiterals() {
   functionTakingUnsignedLong(false);
   // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'bool' -> 'unsigned long'
   // CHECK-FIXES: functionTakingUnsignedLong(0u);
+  // CHECK-FIXES-UPPER-CASE: functionTakingUnsignedLong(0U);
 
   functionTakingSignedChar(true);
   // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: implicit conversion 'bool' -> 'signed char'
@@ -103,6 +108,7 @@ void implicitConversionFromBoolLiterals() {
   functionTakingFloat(false);
   // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: implicit conversion 'bool' -> 'float'
   // CHECK-FIXES: functionTakingFloat(0.0f);
+  // CHECK-FIXES-UPPER-CASE: functionTakingFloat(0.0F);
 
   functionTakingDouble(true);
   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'bool' -> 'double'
@@ -160,11 +166,13 @@ void implicitConversionToBoolSimpleCases() {
   functionTakingBool(unsignedLong);
   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'unsigned long' -> 'bool'
   // CHECK-FIXES: functionTakingBool(unsignedLong != 0u);
+  // CHECK-FIXES-UPPER-CASE: functionTakingBool(unsignedLong != 0U);
 
   float floating = 0.0f;
   functionTakingBool(floating);
   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: functionTakingBool(floating != 0.0f);
+  // CHECK-FIXES-UPPER-CASE: functionTakingBool(floating != 0.0F);
 
   double doubleFloating = 1.0f;
   functionTakingBool(doubleFloating);
@@ -194,6 +202,7 @@ void implicitConversionToBoolInSingleExpressions() {
   boolComingFromFloat = floating;
   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: boolComingFromFloat = (floating != 0.0f);
+  // CHECK-FIXES-UPPER-CASE: boolComingFromFloat = (floating != 0.0F);
 
   signed char character = 'a';
   bool boolComingFromChar;
@@ -288,6 +297,7 @@ void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() {
   functionTakingBool(-0.0f);
   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: functionTakingBool((-0.0f) != 0.0f);
+  // CHECK-FIXES-UPPER-CASE: functionTakingBool((-0.0f) != 0.0F);
 
   functionTakingBool(-0.0);
   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: implicit conversion 'double' -> 'bool'

diff  --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp
index d6e7dcc4d8867b..c4b7a77b92f0a5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion.cpp
@@ -1,4 +1,8 @@
 // RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t
+// RUN: %check_clang_tidy -check-suffix=UPPER-CASE %s readability-implicit-bool-conversion %t -- \
+// RUN:     -config='{CheckOptions: { \
+// RUN:         readability-implicit-bool-conversion.UseUpperCaseLiteralSuffix: true \
+// RUN:     }}'
 
 // We need NULL macro, but some buildbots don't like including <cstddef> header
 // This is a portable way of getting it to work
@@ -99,6 +103,7 @@ void implicitConversionFromBoolLiterals() {
   functionTaking<unsigned long>(false);
   // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'bool' -> 'unsigned long'
   // CHECK-FIXES: functionTaking<unsigned long>(0u);
+  // CHECK-FIXES-UPPER-CASE: functionTaking<unsigned long>(0U);
 
   functionTaking<signed char>(true);
   // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: implicit conversion 'bool' -> 'signed char'
@@ -107,6 +112,7 @@ void implicitConversionFromBoolLiterals() {
   functionTaking<float>(false);
   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: implicit conversion 'bool' -> 'float'
   // CHECK-FIXES: functionTaking<float>(0.0f);
+  // CHECK-FIXES-UPPER-CASE: functionTaking<float>(0.0F);
 
   functionTaking<double>(true);
   // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: implicit conversion 'bool' -> 'double'
@@ -178,11 +184,13 @@ void implicitConversionToBoolSimpleCases() {
   functionTaking<bool>(unsignedLong);
   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'unsigned long' -> 'bool'
   // CHECK-FIXES: functionTaking<bool>(unsignedLong != 0u);
+  // CHECK-FIXES-UPPER-CASE: functionTaking<bool>(unsignedLong != 0U);
 
   float floating = 0.0f;
   functionTaking<bool>(floating);
   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: functionTaking<bool>(floating != 0.0f);
+  // CHECK-FIXES-UPPER-CASE: functionTaking<bool>(floating != 0.0F);
 
   double doubleFloating = 1.0f;
   functionTaking<bool>(doubleFloating);
@@ -215,6 +223,7 @@ void implicitConversionToBoolInSingleExpressions() {
   bool boolComingFromFloat = floating;
   // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: bool boolComingFromFloat = floating != 0.0f;
+  // CHECK-FIXES-UPPER-CASE: bool boolComingFromFloat = floating != 0.0F;
 
   signed char character = 'a';
   bool boolComingFromChar = character;
@@ -240,6 +249,7 @@ void implicitConversionToBoolInComplexExpressions() {
   bool boolComingFromFloating = floating - 0.3f || boolean;
   // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: bool boolComingFromFloating = ((floating - 0.3f) != 0.0f) || boolean;
+  // CHECK-FIXES-UPPER-CASE: bool boolComingFromFloating = ((floating - 0.3f) != 0.0F) || boolean;
 
   double doubleFloating = 0.3;
   bool boolComingFromDoubleFloating = (doubleFloating - 0.4) && boolean;
@@ -257,6 +267,7 @@ void implicitConversionInNegationExpressions() {
   bool boolComingFromNegatedFloat = ! floating;
   // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: bool boolComingFromNegatedFloat = floating == 0.0f;
+  // CHECK-FIXES-UPPER-CASE: bool boolComingFromNegatedFloat = floating == 0.0F;
 
   signed char character = 'a';
   bool boolComingFromNegatedChar = (! character);
@@ -284,6 +295,7 @@ void implicitConversionToBoolInControlStatements() {
   while (floating) {}
   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: while (floating != 0.0f) {}
+  // CHECK-FIXES-UPPER-CASE: while (floating != 0.0F) {}
 
   double doubleFloating = 0.4;
   do {} while (doubleFloating);
@@ -296,6 +308,7 @@ bool implicitConversionToBoolInReturnValue() {
   return floating;
   // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: return floating != 0.0f;
+  // CHECK-FIXES-UPPER-CASE: return floating != 0.0F;
 }
 
 void implicitConversionToBoolFromLiterals() {
@@ -355,6 +368,7 @@ void implicitConversionToBoolFromUnaryMinusAndZeroLiterals() {
   functionTaking<bool>(-0.0f);
   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'float' -> 'bool'
   // CHECK-FIXES: functionTaking<bool>((-0.0f) != 0.0f);
+  // CHECK-FIXES-UPPER-CASE: functionTaking<bool>((-0.0f) != 0.0F);
 
   functionTaking<bool>(-0.0);
   // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: implicit conversion 'double' -> 'bool'


        


More information about the cfe-commits mailing list