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' _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits