https://github.com/qt-tatiana updated https://github.com/llvm/llvm-project/pull/113144
>From 34ee6f5836efe3acddbdd1c9810af358b8c4f981 Mon Sep 17 00:00:00 2001 From: Tatiana Borisova <tatiana.boris...@qt.io> Date: Thu, 17 Oct 2024 18:00:08 +0200 Subject: [PATCH 1/8] [clang-tidy] Create a check for signed and unsigned integers comparison - modernize-use-integer-sign-comparison check performs comparisons between signed and unsigned integer types mathematically correct. If C++20 is supported the check replaces integers comparisons to std::cmp_{} functions and add <utility> include. - qt-integer-sign-comparison check works like an alias of modernize-use-integer-sign-comparison for C++20. If only C++17 is supported the check replaces integers comparisons to q20::cmp_{} functions and add <QtCore/q20utility.h> include. The check assumes the analysed code is Qt-based code. - add qt module for qt-related checks. --- clang-tools-extra/clang-tidy/CMakeLists.txt | 2 + .../clang-tidy/ClangTidyForceLinker.h | 5 + .../clang-tidy/modernize/CMakeLists.txt | 1 + .../UseIntegerSignComparisonCheck.cpp | 169 ++++++++++++++++++ .../modernize/UseIntegerSignComparisonCheck.h | 46 +++++ .../clang-tidy/qt/CMakeLists.txt | 26 +++ .../clang-tidy/qt/QtTidyModule.cpp | 46 +++++ clang-tools-extra/docs/ReleaseNotes.rst | 17 ++ .../docs/clang-tidy/checks/list.rst | 3 + .../modernize/use-integer-sign-comparison.rst | 43 +++++ .../checks/qt/IntegerCrossSignComparison.rst | 64 +++++++ clang-tools-extra/docs/clang-tidy/index.rst | 1 + .../modernize/use-integer-sign-comparison.cpp | 61 +++++++ .../qt/qt-integer-sign-comparison.cpp | 61 +++++++ 14 files changed, 545 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h create mode 100644 clang-tools-extra/clang-tidy/qt/CMakeLists.txt create mode 100644 clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst create mode 100644 clang-tools-extra/docs/clang-tidy/checks/qt/IntegerCrossSignComparison.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp diff --git a/clang-tools-extra/clang-tidy/CMakeLists.txt b/clang-tools-extra/clang-tidy/CMakeLists.txt index 83a3236131dc93..56ef16a8fb37d6 100644 --- a/clang-tools-extra/clang-tidy/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/CMakeLists.txt @@ -75,6 +75,7 @@ add_subdirectory(objc) add_subdirectory(openmp) add_subdirectory(performance) add_subdirectory(portability) +add_subdirectory(qt) add_subdirectory(readability) add_subdirectory(zircon) set(ALL_CLANG_TIDY_CHECKS @@ -99,6 +100,7 @@ set(ALL_CLANG_TIDY_CHECKS clangTidyOpenMPModule clangTidyPerformanceModule clangTidyPortabilityModule + clangTidyQtModule clangTidyReadabilityModule clangTidyZirconModule ) diff --git a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h index adde9136ff1dd5..3c777f42520223 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h +++ b/clang-tools-extra/clang-tidy/ClangTidyForceLinker.h @@ -127,6 +127,11 @@ extern volatile int PortabilityModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED PortabilityModuleAnchorDestination = PortabilityModuleAnchorSource; +// This anchor is used to force the linker to link the QtClangTidyModule. +extern volatile int QtClangTidyModuleAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED QtClangTidyModuleAnchorDestination = + QtClangTidyModuleAnchorSource; + // This anchor is used to force the linker to link the ReadabilityModule. extern volatile int ReadabilityModuleAnchorSource; static int LLVM_ATTRIBUTE_UNUSED ReadabilityModuleAnchorDestination = diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873a..bab1167fb15ff2 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -36,6 +36,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseEmplaceCheck.cpp UseEqualsDefaultCheck.cpp UseEqualsDeleteCheck.cpp + UseIntegerSignComparisonCheck.cpp UseNodiscardCheck.cpp UseNoexceptCheck.cpp UseNullptrCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp new file mode 100644 index 00000000000000..8f394a14a9b0c4 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp @@ -0,0 +1,169 @@ +//===--- UseIntegerSignComparisonCheck.cpp - clang-tidy -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "UseIntegerSignComparisonCheck.h" +#include "clang/AST/Expr.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; +using namespace clang::ast_matchers::internal; + +namespace clang::tidy::modernize { + +UseIntegerSignComparisonCheck::UseIntegerSignComparisonCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", + utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()), + IsQtApplication(Options.get("IsQtApplication", false)) {} + +void UseIntegerSignComparisonCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IsQtApplication", IsQtApplication); +} + +void UseIntegerSignComparisonCheck::registerMatchers(MatchFinder *Finder) { + const auto SignedIntCastExpr = intCastExpression(true, "sIntCastExpression"); + const auto UnSignedIntCastExpr = + intCastExpression(false, "uIntCastExpression"); + + // Flag all operators "==", "<=", ">=", "<", ">", "!=" + // that are used between signed/unsigned + const auto CompareOperator = + expr(binaryOperator(hasAnyOperatorName("==", "<=", ">=", "<", ">", "!="), + anyOf(allOf(hasLHS(SignedIntCastExpr), + hasRHS(UnSignedIntCastExpr)), + allOf(hasLHS(UnSignedIntCastExpr), + hasRHS(SignedIntCastExpr))))) + .bind("intComparison"); + + Finder->addMatcher(CompareOperator, this); +} + +BindableMatcher<clang::Stmt> UseIntegerSignComparisonCheck::intCastExpression( + bool IsSigned, const std::string &CastBindName) const { + auto IntTypeExpr = expr(); + if (IsSigned) { + IntTypeExpr = expr(hasType(qualType(isInteger(), isSignedInteger()))); + } else { + IntTypeExpr = + expr(hasType(qualType(isInteger(), unless(isSignedInteger())))); + } + + const auto ImplicitCastExpr = + implicitCastExpr(hasSourceExpression(IntTypeExpr)).bind(CastBindName); + + const auto CStyleCastExpr = cStyleCastExpr(has(ImplicitCastExpr)); + const auto StaticCastExpr = cxxStaticCastExpr(has(ImplicitCastExpr)); + const auto FunctionalCastExpr = cxxFunctionalCastExpr(has(ImplicitCastExpr)); + + return traverse(TK_AsIs, expr(anyOf(ImplicitCastExpr, CStyleCastExpr, + StaticCastExpr, FunctionalCastExpr))); +} + +std::string +UseIntegerSignComparisonCheck::parseOpCode(BinaryOperator::Opcode code) const { + switch (code) { + case BO_LT: + return std::string("cmp_less"); + case BO_GT: + return std::string("cmp_greater"); + case BO_LE: + return std::string("cmp_less_equal"); + case BO_GE: + return std::string("cmp_greater_equal"); + case BO_EQ: + return std::string("cmp_equal"); + case BO_NE: + return std::string("cmp_not_equal"); + default: + return std::string(); + } +} + +void UseIntegerSignComparisonCheck::registerPPCallbacks( + const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + IncludeInserter.registerPreprocessor(PP); +} + +void UseIntegerSignComparisonCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *SignedCastExpression = + Result.Nodes.getNodeAs<ImplicitCastExpr>("sIntCastExpression"); + const auto *UnSignedCastExpression = + Result.Nodes.getNodeAs<ImplicitCastExpr>("uIntCastExpression"); + assert(SignedCastExpression); + assert(UnSignedCastExpression); + + // Ignore the match if we know that the signed int value is not negative. + Expr::EvalResult EVResult; + if (!SignedCastExpression->isValueDependent() && + SignedCastExpression->getSubExpr()->EvaluateAsInt(EVResult, + *Result.Context)) { + llvm::APSInt SValue = EVResult.Val.getInt(); + if (SValue.isNonNegative()) + return; + } + + const auto *BinaryOp = + Result.Nodes.getNodeAs<BinaryOperator>("intComparison"); + if (BinaryOp == nullptr) + return; + + auto OpCode = BinaryOp->getOpcode(); + const auto *LHS = BinaryOp->getLHS()->IgnoreParenImpCasts(); + const auto *RHS = BinaryOp->getRHS()->IgnoreParenImpCasts(); + if (LHS == nullptr || RHS == nullptr) + return; + + StringRef LHSString(Lexer::getSourceText( + CharSourceRange::getTokenRange(LHS->getSourceRange()), + *Result.SourceManager, getLangOpts())); + + StringRef RHSString(Lexer::getSourceText( + CharSourceRange::getTokenRange(RHS->getSourceRange()), + *Result.SourceManager, getLangOpts())); + + DiagnosticBuilder Diag = + diag(BinaryOp->getBeginLoc(), + "comparison between 'signed' and 'unsigned' integers"); + + if (!(getLangOpts().CPlusPlus17 && IsQtApplication) && + !getLangOpts().CPlusPlus20) + return; + + std::string CmpNamespace; + std::string CmpInclude; + if (getLangOpts().CPlusPlus17 && IsQtApplication) { + CmpInclude = "<QtCore/q20utility.h>"; + CmpNamespace = std::string("q20::") + parseOpCode(OpCode); + } + + if (getLangOpts().CPlusPlus20) { + CmpInclude = "<utility>"; + CmpNamespace = std::string("std::") + parseOpCode(OpCode); + } + + // Use qt-use-integer-sign-comparison when C++17 is available and only for Qt + // apps. Prefer modernize-use-integer-sign-comparison when C++20 is available! + Diag << FixItHint::CreateReplacement( + CharSourceRange::getTokenRange(BinaryOp->getBeginLoc(), + BinaryOp->getEndLoc()), + StringRef(std::string(CmpNamespace) + std::string("(") + + std::string(LHSString) + std::string(", ") + + std::string(RHSString) + std::string(")"))); + + // If there is no include for cmp_{*} functions, we'll add it. + Diag << IncludeInserter.createIncludeInsertion( + Result.SourceManager->getFileID(BinaryOp->getBeginLoc()), + StringRef(CmpInclude)); +} + +} // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h new file mode 100644 index 00000000000000..13c6ea9f74ec32 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h @@ -0,0 +1,46 @@ +//===--- UseIntegerSignComparisonCheck.h - clang-tidy -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEINTEGERSIGNCOMPARISONCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEINTEGERSIGNCOMPARISONCHECK_H + +#include "../ClangTidyCheck.h" +#include "../utils/IncludeInserter.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +namespace clang::tidy::modernize { + +/// Class detects comparisons between signed and unsigned integers +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-integer-sign-comparison.html +class UseIntegerSignComparisonCheck : public ClangTidyCheck { +public: + UseIntegerSignComparisonCheck(StringRef Name, ClangTidyContext *Context); + + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, + Preprocessor *ModuleExpanderPP) override; + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } + +private: + ast_matchers::internal::BindableMatcher<clang::Stmt> + intCastExpression(bool IsSigned, const std::string &CastBindName) const; + std::string parseOpCode(BinaryOperator::Opcode code) const; + + utils::IncludeInserter IncludeInserter; + bool IsQtApplication = false; +}; + +} // namespace clang::tidy::modernize + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEINTEGERSIGNCOMPARISONCHECK_H diff --git a/clang-tools-extra/clang-tidy/qt/CMakeLists.txt b/clang-tools-extra/clang-tidy/qt/CMakeLists.txt new file mode 100644 index 00000000000000..5133c47b3031ee --- /dev/null +++ b/clang-tools-extra/clang-tidy/qt/CMakeLists.txt @@ -0,0 +1,26 @@ +set(LLVM_LINK_COMPONENTS + FrontendOpenMP + Support +) + +add_clang_library(clangTidyQtModule + QtTidyModule.cpp + + LINK_LIBS + clangTidy + clangTidyModernizeModule + clangTidyUtils + + DEPENDS + omp_gen + ClangDriverOptions + ) + +clang_target_link_libraries(clangTidyQtModule + PRIVATE + clangAST + clangASTMatchers + clangBasic + clangLex + clangTooling + ) diff --git a/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp b/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp new file mode 100644 index 00000000000000..3f2c5ec9a4fa21 --- /dev/null +++ b/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp @@ -0,0 +1,46 @@ +//===-- QtTidyModule.cpp - clang-tidy ----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "../ClangTidy.h" +#include "../ClangTidyModule.h" +#include "../ClangTidyModuleRegistry.h" +#include "../modernize/UseIntegerSignComparisonCheck.h" + +namespace clang::tidy { +namespace qt { + +/// A module containing checks of the C++ Core Guidelines +class QtClangTidyModule : public ClangTidyModule { +public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck<modernize::UseIntegerSignComparisonCheck>( + "qt-integer-sign-comparison"); + } + + ClangTidyOptions getModuleOptions() override { + ClangTidyOptions Options; + ClangTidyOptions::OptionMap &Opts = Options.CheckOptions; + + Opts["qt-integer-sign-comparison." + "IsQtApplication"] = "true"; + + return Options; + } +}; + +// Register the LLVMTidyModule using this statically initialized variable. +static ClangTidyModuleRegistry::Add<QtClangTidyModule> + X("qt-module", "Adds checks for the Qt framework Guidelines."); + +} // namespace qt + +// This anchor is used to force the linker to link in the generated object file +// and thus register the QtClangTidyModule. +volatile int QtClangTidyModuleAnchorSource = 0; + +} // namespace clang::tidy diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index e8148e06b6af28..ba9922b835d230 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -129,6 +129,15 @@ New checks Finds cases when an uninstantiated virtual member function in a template class causes cross-compiler incompatibility. +- New :doc:`modernize-use-integer-sign-comparison + <clang-tidy/checks/modernize/use-integer-sign-comparison>` check. + + Performs comparisons between signed and unsigned integer types + mathematically correct. If C++20 is supported a fix-it replaces + integers comparisons to + std::cmp_{equal,not_equal,{less,greater}{,_equal}} functions. + + New check aliases ^^^^^^^^^^^^^^^^^ @@ -136,6 +145,14 @@ New check aliases :doc:`bugprone-sizeof-expression <clang-tidy/checks/bugprone/sizeof-expression>` was added. +- New alias :doc:`qt-integer-sign-comparison + <clang-tidy/checks/qt/integer-sign-comparison>` to + doc:`modernize-use-integer-sign-comparison + <clang-tidy/checks/modernize/use-integer-sign-comparison>` check. + If C++17 is supported, the fix-it replaces integers comparisons to + q20::cmp_{equal,not_equal,{less,greater}{,_equal}} functions. + The check assumes the analysed code is Qt-based code. + Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 0082234f5ed31b..f1b9f032c76615 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -30,6 +30,7 @@ Clang-Tidy Checks openmp/* performance/* portability/* + qt/* readability/* zircon/* @@ -300,6 +301,7 @@ Clang-Tidy Checks :doc:`modernize-use-emplace <modernize/use-emplace>`, "Yes" :doc:`modernize-use-equals-default <modernize/use-equals-default>`, "Yes" :doc:`modernize-use-equals-delete <modernize/use-equals-delete>`, "Yes" + :doc:`modernize-use-integer-sign-comparison <modernize/use-integer-sign-comparison>`, "Yes" :doc:`modernize-use-nodiscard <modernize/use-nodiscard>`, "Yes" :doc:`modernize-use-noexcept <modernize/use-noexcept>`, "Yes" :doc:`modernize-use-nullptr <modernize/use-nullptr>`, "Yes" @@ -348,6 +350,7 @@ Clang-Tidy Checks :doc:`portability-restrict-system-includes <portability/restrict-system-includes>`, "Yes" :doc:`portability-simd-intrinsics <portability/simd-intrinsics>`, :doc:`portability-std-allocator-const <portability/std-allocator-const>`, + :doc:`qt-integer-sign-comparison <qt/integer-sign-comparison>`, "Yes" :doc:`portability-template-virtual-member-function <portability/template-virtual-member-function>`, :doc:`readability-avoid-const-params-in-decls <readability/avoid-const-params-in-decls>`, "Yes" :doc:`readability-avoid-nested-conditional-operator <readability/avoid-nested-conditional-operator>`, diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst new file mode 100644 index 00000000000000..21bee8ec16b17d --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst @@ -0,0 +1,43 @@ +.. title:: clang-tidy - modernize-use-integer-sign-comparison + +modernize-use-integer-sign-comparison +===================================== + +The check detects comparison between signed and unsigned integer values. +If C++20 is supported, the check suggests a fix-it. + +Examples of fixes created by the check: + +.. code-block:: c++ + + uint func(int bla) + { + uint result; + if (result == bla) + return 0; + + return 1; + } + +becomes + +.. code-block:: c++ + + #include <utility> + + uint func(int bla) + { + uint result; + if (std::cmp_equal(result, bla)) + return 0; + + return 1; + } + +Options +------- + +.. option:: IncludeStyle + + A string specifying which include-style is used, `llvm` or `google`. Default + is `llvm`. diff --git a/clang-tools-extra/docs/clang-tidy/checks/qt/IntegerCrossSignComparison.rst b/clang-tools-extra/docs/clang-tidy/checks/qt/IntegerCrossSignComparison.rst new file mode 100644 index 00000000000000..1f9e1089826ce9 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/qt/IntegerCrossSignComparison.rst @@ -0,0 +1,64 @@ +.. title:: clang-tidy - qt-integer-sign-comparison + +qt-integer-sign-comparison +============================= + +The check detects comparison between signed and unsigned integer values. +If C++20 is supported, the check suggests a std related fix-it. +If C++17 is supported, the check suggests a Qt related fix-it. + +Examples of fixes created by the check: + +.. code-block:: c++ + + uint func(int bla) + { + uint result; + if (result == bla) + return 0; + + return 1; + } + +in C++17 becomes + +.. code-block:: c++ + + <QtCore/q20utility.h> + + uint func(int bla) + { + uint result; + if (q20::cmp_equal(result, bla)) + return 0; + + return 1; + } + +in C++20 becomes + +.. code-block:: c++ + + #include <utility> + + uint func(int bla) + { + uint result; + if (std::cmp_equal(result, bla)) + return 0; + + return 1; + } + +Options +------- + +.. option:: IncludeStyle + + A string specifying which include-style is used, `llvm` or `google`. Default + is `llvm`. + +.. option:: IsQtApplication + + When `true` (default `false`), then it is assumed that the code being analyzed + is the Qt-based code. diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst index a4233d5d8e2694..9663ed03c8734d 100644 --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -84,6 +84,7 @@ Name prefix Description ``performance-`` Checks that target performance-related issues. ``portability-`` Checks that target portability-related issues that don't relate to any particular coding style. +``qt-`` Checks related to Qt framework. ``readability-`` Checks that target readability-related issues that don't relate to any particular coding style. ``zircon-`` Checks related to Zircon kernel coding conventions. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp new file mode 100644 index 00000000000000..b580e2dfc6731d --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp @@ -0,0 +1,61 @@ +// RUN: %check_clang_tidy -std=c++20 %s modernize-use-integer-sign-comparison %t + +// The code that triggers the check +#define MAX_MACRO(a, b) (a < b) ? b : a +namespace std { + +unsigned int FuncParameters(int bla) { + unsigned int result; + if (result == bla) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_equal(result, bla)) + + return 1; +} + +template <typename T> +void TemplateFuncParameters(T val) { + unsigned long uL = 0; + if (val >= uL) + return; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_greater_equal(val, uL)) +} + +int AllComparisons() { + unsigned int uVar = 42; + unsigned short uArray[2] = {0, 1}; + + int sVar = -42; + short sArray[2] = {-1, -2}; + + if (uVar < sVar) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_less(uVar, sVar)) + + (uVar != sVar) ? uVar = sVar + : sVar = uVar; +// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: (std::cmp_not_equal(uVar, sVar)) ? uVar = sVar + + while (uArray[0] <= sArray[0]) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:12: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: while (std::cmp_less_equal(uArray[0], sArray[0])) + + if (uArray[1] > sArray[1]) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_greater(uArray[1], sArray[1])) + + MAX_MACRO(uVar, sArray[0]); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] + + FuncParameters(uVar); + TemplateFuncParameters(sVar); + + return 0; +} +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp new file mode 100644 index 00000000000000..bb9e691e7cb797 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp @@ -0,0 +1,61 @@ +// RUN: %check_clang_tidy -std=c++17 %s qt-integer-sign-comparison %t + +// The code that triggers the check +#define MAX_MACRO(a, b) (a < b) ? b : a +namespace std { + +unsigned int FuncParameters(int bla) { + unsigned int result; + if (result == bla) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] +// CHECK-FIXES: if (q20::cmp_equal(result, bla)) + + return 1; +} + +template <typename T> +void TemplateFuncParameters(T val) { + unsigned long uL = 0; + if (val >= uL) + return; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] +// CHECK-FIXES: if (q20::cmp_greater_equal(val, uL)) +} + +int AllComparisons() { + unsigned int uVar = 42; + unsigned short uArray[2] = {0, 1}; + + int sVar = -42; + short sArray[2] = {-1, -2}; + + if (uVar < sVar) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] +// CHECK-FIXES: if (q20::cmp_less(uVar, sVar)) + + (uVar != sVar) ? uVar = sVar + : sVar = uVar; +// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] +// CHECK-FIXES: (q20::cmp_not_equal(uVar, sVar)) ? uVar = sVar + + while (uArray[0] <= sArray[0]) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:12: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] +// CHECK-FIXES: while (q20::cmp_less_equal(uArray[0], sArray[0])) + + if (uArray[1] > sArray[1]) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] +// CHECK-FIXES: if (q20::cmp_greater(uArray[1], sArray[1])) + + MAX_MACRO(uVar, sArray[0]); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] + + FuncParameters(uVar); + TemplateFuncParameters(sVar); + + return 0; +} +} >From b013b2c5ee3db7e963fb12f99c0750ca6b4ab36a Mon Sep 17 00:00:00 2001 From: Tatiana Borisova <tatiana.boris...@qt.io> Date: Thu, 24 Oct 2024 11:59:23 +0200 Subject: [PATCH 2/8] fixup! [clang-tidy] Create a check for signed and unsigned integers comparison --- .../modernize/ModernizeTidyModule.cpp | 3 ++ .../UseIntegerSignComparisonCheck.cpp | 33 +++++++++---------- .../modernize/UseIntegerSignComparisonCheck.h | 1 + .../clang-tidy/qt/CMakeLists.txt | 4 +-- .../clang-tidy/qt/QtTidyModule.cpp | 8 +++-- clang-tools-extra/docs/ReleaseNotes.rst | 21 ++++++------ .../modernize/use-integer-sign-comparison.rst | 15 +++------ ...arison.rst => integer-sign-comparison.rst} | 10 ++++-- 8 files changed, 50 insertions(+), 45 deletions(-) rename clang-tools-extra/docs/clang-tidy/checks/qt/{IntegerCrossSignComparison.rst => integer-sign-comparison.rst} (76%) diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 18607593320635..fc46c72982fdce 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -37,6 +37,7 @@ #include "UseEmplaceCheck.h" #include "UseEqualsDefaultCheck.h" #include "UseEqualsDeleteCheck.h" +#include "UseIntegerSignComparisonCheck.h" #include "UseNodiscardCheck.h" #include "UseNoexceptCheck.h" #include "UseNullptrCheck.h" @@ -76,6 +77,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck<PassByValueCheck>("modernize-pass-by-value"); CheckFactories.registerCheck<UseDesignatedInitializersCheck>( "modernize-use-designated-initializers"); + CheckFactories.registerCheck<UseIntegerSignComparisonCheck>( + "modernize-use-integer-sign-comparison"); CheckFactories.registerCheck<UseRangesCheck>("modernize-use-ranges"); CheckFactories.registerCheck<UseStartsEndsWithCheck>( "modernize-use-starts-ends-with"); diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp index 8f394a14a9b0c4..444e3de0e787b9 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp @@ -22,11 +22,13 @@ UseIntegerSignComparisonCheck::UseIntegerSignComparisonCheck( IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", utils::IncludeSorter::IS_LLVM), areDiagsSelfContained()), - IsQtApplication(Options.get("IsQtApplication", false)) {} + IsQtApplication(Options.get("IsQtApplication", false)), + StringsMatchHeader(Options.get("StringsMatchHeader", "<utility>")) {} void UseIntegerSignComparisonCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "IsQtApplication", IsQtApplication); + Options.store(Opts, "StringsMatchHeader", StringsMatchHeader); } void UseIntegerSignComparisonCheck::registerMatchers(MatchFinder *Finder) { @@ -84,7 +86,7 @@ UseIntegerSignComparisonCheck::parseOpCode(BinaryOperator::Opcode code) const { case BO_NE: return std::string("cmp_not_equal"); default: - return std::string(); + return {}; } } @@ -107,7 +109,7 @@ void UseIntegerSignComparisonCheck::check( if (!SignedCastExpression->isValueDependent() && SignedCastExpression->getSubExpr()->EvaluateAsInt(EVResult, *Result.Context)) { - llvm::APSInt SValue = EVResult.Val.getInt(); + const llvm::APSInt SValue = EVResult.Val.getInt(); if (SValue.isNonNegative()) return; } @@ -117,18 +119,18 @@ void UseIntegerSignComparisonCheck::check( if (BinaryOp == nullptr) return; - auto OpCode = BinaryOp->getOpcode(); - const auto *LHS = BinaryOp->getLHS()->IgnoreParenImpCasts(); - const auto *RHS = BinaryOp->getRHS()->IgnoreParenImpCasts(); - if (LHS == nullptr || RHS == nullptr) + const BinaryOperator::Opcode OpCode = BinaryOp->getOpcode(); + const auto *Lhs = BinaryOp->getLHS()->IgnoreParenImpCasts(); + const auto *Rhs = BinaryOp->getRHS()->IgnoreParenImpCasts(); + if (Lhs == nullptr || Rhs == nullptr) return; - StringRef LHSString(Lexer::getSourceText( - CharSourceRange::getTokenRange(LHS->getSourceRange()), + const StringRef LhsString(Lexer::getSourceText( + CharSourceRange::getTokenRange(Lhs->getSourceRange()), *Result.SourceManager, getLangOpts())); - StringRef RHSString(Lexer::getSourceText( - CharSourceRange::getTokenRange(RHS->getSourceRange()), + const StringRef RhsString(Lexer::getSourceText( + CharSourceRange::getTokenRange(Rhs->getSourceRange()), *Result.SourceManager, getLangOpts())); DiagnosticBuilder Diag = @@ -140,14 +142,11 @@ void UseIntegerSignComparisonCheck::check( return; std::string CmpNamespace; - std::string CmpInclude; if (getLangOpts().CPlusPlus17 && IsQtApplication) { - CmpInclude = "<QtCore/q20utility.h>"; CmpNamespace = std::string("q20::") + parseOpCode(OpCode); } if (getLangOpts().CPlusPlus20) { - CmpInclude = "<utility>"; CmpNamespace = std::string("std::") + parseOpCode(OpCode); } @@ -157,13 +156,13 @@ void UseIntegerSignComparisonCheck::check( CharSourceRange::getTokenRange(BinaryOp->getBeginLoc(), BinaryOp->getEndLoc()), StringRef(std::string(CmpNamespace) + std::string("(") + - std::string(LHSString) + std::string(", ") + - std::string(RHSString) + std::string(")"))); + std::string(LhsString) + std::string(", ") + + std::string(RhsString) + std::string(")"))); // If there is no include for cmp_{*} functions, we'll add it. Diag << IncludeInserter.createIncludeInsertion( Result.SourceManager->getFileID(BinaryOp->getBeginLoc()), - StringRef(CmpInclude)); + StringsMatchHeader); } } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h index 13c6ea9f74ec32..44668c0656072f 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h @@ -39,6 +39,7 @@ class UseIntegerSignComparisonCheck : public ClangTidyCheck { utils::IncludeInserter IncludeInserter; bool IsQtApplication = false; + const StringRef StringsMatchHeader; }; } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/qt/CMakeLists.txt b/clang-tools-extra/clang-tidy/qt/CMakeLists.txt index 5133c47b3031ee..9b252515bba3e6 100644 --- a/clang-tools-extra/clang-tidy/qt/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/qt/CMakeLists.txt @@ -14,7 +14,7 @@ add_clang_library(clangTidyQtModule DEPENDS omp_gen ClangDriverOptions - ) +) clang_target_link_libraries(clangTidyQtModule PRIVATE @@ -23,4 +23,4 @@ clang_target_link_libraries(clangTidyQtModule clangBasic clangLex clangTooling - ) +) diff --git a/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp b/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp index 3f2c5ec9a4fa21..3f1362129ca9b2 100644 --- a/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp @@ -1,4 +1,4 @@ -//===-- QtTidyModule.cpp - clang-tidy ----------------------===// +//===--- QtTidyModule.cpp - clang-tidy ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -26,8 +26,10 @@ class QtClangTidyModule : public ClangTidyModule { ClangTidyOptions Options; ClangTidyOptions::OptionMap &Opts = Options.CheckOptions; - Opts["qt-integer-sign-comparison." - "IsQtApplication"] = "true"; + Opts["qt-integer-sign-comparison.IncludeStyle"] = "llvm"; + Opts["qt-integer-sign-comparison.IsQtApplication"] = "true"; + Opts["qt-integer-sign-comparison.StringsMatchHeader"] = + "<QtCore/q20utility.h>"; return Options; } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index ba9922b835d230..89d16df345f2b5 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -123,20 +123,20 @@ New checks Gives warnings for tagged unions, where the number of tags is different from the number of data members inside the union. -- New :doc:`portability-template-virtual-member-function - <clang-tidy/checks/portability/template-virtual-member-function>` check. - - Finds cases when an uninstantiated virtual member function in a template class - causes cross-compiler incompatibility. - - New :doc:`modernize-use-integer-sign-comparison <clang-tidy/checks/modernize/use-integer-sign-comparison>` check. Performs comparisons between signed and unsigned integer types mathematically correct. If C++20 is supported a fix-it replaces - integers comparisons to - std::cmp_{equal,not_equal,{less,greater}{,_equal}} functions. + integers comparisons to std::cmp_equal, std::cmp_not_equal, + std::cmp_less, std::cmp_greater, std::cmp_less_equal and + std::cmp_greater_equal functions. +- New :doc:`portability-template-virtual-member-function + <clang-tidy/checks/portability/template-virtual-member-function>` check. + + Finds cases when an uninstantiated virtual member function in a template class + causes cross-compiler incompatibility. New check aliases ^^^^^^^^^^^^^^^^^ @@ -147,10 +147,11 @@ New check aliases - New alias :doc:`qt-integer-sign-comparison <clang-tidy/checks/qt/integer-sign-comparison>` to - doc:`modernize-use-integer-sign-comparison + :doc:`modernize-use-integer-sign-comparison <clang-tidy/checks/modernize/use-integer-sign-comparison>` check. If C++17 is supported, the fix-it replaces integers comparisons to - q20::cmp_{equal,not_equal,{less,greater}{,_equal}} functions. + q20::cmp_equal, q20::cmp_not_equal, q20::cmp_less, q20::cmp_greater, + q20::cmp_less_equal and q20::cmp_greater_equal functions. The check assumes the analysed code is Qt-based code. Changes in existing checks diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst index 21bee8ec16b17d..fa7390304437a8 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst @@ -3,8 +3,11 @@ modernize-use-integer-sign-comparison ===================================== -The check detects comparison between signed and unsigned integer values. -If C++20 is supported, the check suggests a fix-it. +Performs comparisons between signed and unsigned integer types +mathematically correct. If C++20 is supported a fix-it replaces +integers comparisons to std::cmp_equal, std::cmp_not_equal, +std::cmp_less, std::cmp_greater, std::cmp_less_equal and +std::cmp_greater_equal functions. Examples of fixes created by the check: @@ -33,11 +36,3 @@ becomes return 1; } - -Options -------- - -.. option:: IncludeStyle - - A string specifying which include-style is used, `llvm` or `google`. Default - is `llvm`. diff --git a/clang-tools-extra/docs/clang-tidy/checks/qt/IntegerCrossSignComparison.rst b/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst similarity index 76% rename from clang-tools-extra/docs/clang-tidy/checks/qt/IntegerCrossSignComparison.rst rename to clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst index 1f9e1089826ce9..a91fe7f714d9b4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/qt/IntegerCrossSignComparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst @@ -3,9 +3,9 @@ qt-integer-sign-comparison ============================= -The check detects comparison between signed and unsigned integer values. -If C++20 is supported, the check suggests a std related fix-it. -If C++17 is supported, the check suggests a Qt related fix-it. +The qt-integer-sign-comparison check is an alias, please see +:doc:`modernize-use-integer-sign-comparison <../modernize/use-integer-sign-comparison>` +for more information. Examples of fixes created by the check: @@ -62,3 +62,7 @@ Options When `true` (default `false`), then it is assumed that the code being analyzed is the Qt-based code. + +.. option:: StringsMatchHeader + A string specifying a include header file to be added by fix-it. Default + is `<utility>`. >From d9a6540c72515370f1a32a9c74eba22a8f71df34 Mon Sep 17 00:00:00 2001 From: Tatiana Borisova <tatiana.boris...@qt.io> Date: Thu, 24 Oct 2024 15:14:19 +0200 Subject: [PATCH 3/8] fixup! fixup! [clang-tidy] Create a check for signed and unsigned integers comparison --- .../modernize/UseIntegerSignComparisonCheck.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp index 444e3de0e787b9..6604f45a557400 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp @@ -15,7 +15,6 @@ using namespace clang::ast_matchers; using namespace clang::ast_matchers::internal; namespace clang::tidy::modernize { - UseIntegerSignComparisonCheck::UseIntegerSignComparisonCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), @@ -120,17 +119,17 @@ void UseIntegerSignComparisonCheck::check( return; const BinaryOperator::Opcode OpCode = BinaryOp->getOpcode(); - const auto *Lhs = BinaryOp->getLHS()->IgnoreParenImpCasts(); - const auto *Rhs = BinaryOp->getRHS()->IgnoreParenImpCasts(); - if (Lhs == nullptr || Rhs == nullptr) + const auto *LHS = BinaryOp->getLHS()->IgnoreParenImpCasts(); + const auto *RHS = BinaryOp->getRHS()->IgnoreParenImpCasts(); + if (LHS == nullptr || RHS == nullptr) return; const StringRef LhsString(Lexer::getSourceText( - CharSourceRange::getTokenRange(Lhs->getSourceRange()), + CharSourceRange::getTokenRange(LHS->getSourceRange()), *Result.SourceManager, getLangOpts())); const StringRef RhsString(Lexer::getSourceText( - CharSourceRange::getTokenRange(Rhs->getSourceRange()), + CharSourceRange::getTokenRange(RHS->getSourceRange()), *Result.SourceManager, getLangOpts())); DiagnosticBuilder Diag = @@ -142,12 +141,10 @@ void UseIntegerSignComparisonCheck::check( return; std::string CmpNamespace; - if (getLangOpts().CPlusPlus17 && IsQtApplication) { - CmpNamespace = std::string("q20::") + parseOpCode(OpCode); - } - if (getLangOpts().CPlusPlus20) { CmpNamespace = std::string("std::") + parseOpCode(OpCode); + } else if (getLangOpts().CPlusPlus17 && IsQtApplication) { + CmpNamespace = std::string("q20::") + parseOpCode(OpCode); } // Use qt-use-integer-sign-comparison when C++17 is available and only for Qt >From c4cbfb717c1005c2ca9441758394ce426158a003 Mon Sep 17 00:00:00 2001 From: Tatiana Borisova <tatiana.boris...@qt.io> Date: Thu, 24 Oct 2024 17:37:24 +0200 Subject: [PATCH 4/8] fixup! fixup! fixup! [clang-tidy] Create a check for signed and unsigned integers comparison --- .../modernize/UseIntegerSignComparisonCheck.cpp | 4 ++-- clang-tools-extra/docs/ReleaseNotes.rst | 11 ++++++----- .../checks/modernize/use-integer-sign-comparison.rst | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp index 6604f45a557400..d81d13edf75c83 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp @@ -119,8 +119,8 @@ void UseIntegerSignComparisonCheck::check( return; const BinaryOperator::Opcode OpCode = BinaryOp->getOpcode(); - const auto *LHS = BinaryOp->getLHS()->IgnoreParenImpCasts(); - const auto *RHS = BinaryOp->getRHS()->IgnoreParenImpCasts(); + const Expr *LHS = BinaryOp->getLHS()->IgnoreParenImpCasts(); + const Expr *RHS = BinaryOp->getRHS()->IgnoreParenImpCasts(); if (LHS == nullptr || RHS == nullptr) return; diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 89d16df345f2b5..9aa602e9a6a989 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -128,9 +128,9 @@ New checks Performs comparisons between signed and unsigned integer types mathematically correct. If C++20 is supported a fix-it replaces - integers comparisons to std::cmp_equal, std::cmp_not_equal, - std::cmp_less, std::cmp_greater, std::cmp_less_equal and - std::cmp_greater_equal functions. + integers comparisons to ``std::cmp_equal``, ``std::cmp_not_equal``, + ``std::cmp_less``, ``std::cmp_greater``, ``std::cmp_less_equal`` and + ``std::cmp_greater_equal`` functions. - New :doc:`portability-template-virtual-member-function <clang-tidy/checks/portability/template-virtual-member-function>` check. @@ -150,8 +150,9 @@ New check aliases :doc:`modernize-use-integer-sign-comparison <clang-tidy/checks/modernize/use-integer-sign-comparison>` check. If C++17 is supported, the fix-it replaces integers comparisons to - q20::cmp_equal, q20::cmp_not_equal, q20::cmp_less, q20::cmp_greater, - q20::cmp_less_equal and q20::cmp_greater_equal functions. + ``q20::cmp_equal``, ``q20::cmp_not_equal``, ``q20::cmp_less``, + ``q20::cmp_greater``, ``q20::cmp_less_equal`` and ``q20::cmp_greater_equal`` + functions. The check assumes the analysed code is Qt-based code. Changes in existing checks diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst index fa7390304437a8..e8edc646c8e2f4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst @@ -5,9 +5,9 @@ modernize-use-integer-sign-comparison Performs comparisons between signed and unsigned integer types mathematically correct. If C++20 is supported a fix-it replaces -integers comparisons to std::cmp_equal, std::cmp_not_equal, -std::cmp_less, std::cmp_greater, std::cmp_less_equal and -std::cmp_greater_equal functions. +integers comparisons to ``std::cmp_equal``, ``std::cmp_not_equal``, +``std::cmp_less``, ``std::cmp_greater``, ``std::cmp_less_equal`` and +``std::cmp_greater_equal`` functions. Examples of fixes created by the check: >From 47cffa5f95d40e873872684b910fd4d8807f4f57 Mon Sep 17 00:00:00 2001 From: Tatiana Borisova <tatiana.boris...@qt.io> Date: Wed, 30 Oct 2024 10:31:46 +0100 Subject: [PATCH 5/8] fixup! fixup! fixup! fixup! [clang-tidy] Create a check for signed and unsigned integers comparison --- .../UseIntegerSignComparisonCheck.cpp | 146 ++++++++++-------- .../modernize/UseIntegerSignComparisonCheck.h | 5 - .../clang-tidy/qt/CMakeLists.txt | 2 +- .../clang-tidy/qt/QtTidyModule.cpp | 2 - clang-tools-extra/docs/ReleaseNotes.rst | 7 +- .../modernize/use-integer-sign-comparison.rst | 7 +- .../modernize/use-integer-sign-comparison.cpp | 30 ++-- .../qt/qt-integer-sign-comparison.cpp | 30 ++-- 8 files changed, 119 insertions(+), 110 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp index d81d13edf75c83..1d9014ad84702f 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp @@ -15,19 +15,54 @@ using namespace clang::ast_matchers; using namespace clang::ast_matchers::internal; namespace clang::tidy::modernize { +static BindableMatcher<clang::Stmt> intCastExpression(bool IsSigned, + const std::string &CastBindName) { + auto IntTypeExpr = IsSigned + ? expr(hasType(hasCanonicalType(qualType(isInteger(), isSignedInteger())))) + : expr(hasType(hasCanonicalType(qualType(isInteger(), unless(isSignedInteger()))))); + + const auto ImplicitCastExpr = + implicitCastExpr(hasSourceExpression(IntTypeExpr)).bind(CastBindName); + + const auto CStyleCastExpr = cStyleCastExpr(has(ImplicitCastExpr)); + const auto StaticCastExpr = cxxStaticCastExpr(has(ImplicitCastExpr)); + const auto FunctionalCastExpr = cxxFunctionalCastExpr(has(ImplicitCastExpr)); + + return expr(anyOf(ImplicitCastExpr, CStyleCastExpr, + StaticCastExpr, FunctionalCastExpr)); +} + +static StringRef parseOpCode(BinaryOperator::Opcode Code) { + switch (Code) { + case BO_LT: + return "cmp_less"; + case BO_GT: + return "cmp_greater"; + case BO_LE: + return "cmp_less_equal"; + case BO_GE: + return "cmp_greater_equal"; + case BO_EQ: + return "cmp_equal"; + case BO_NE: + return "cmp_not_equal"; + default: + return ""; + } +} + UseIntegerSignComparisonCheck::UseIntegerSignComparisonCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", utils::IncludeSorter::IS_LLVM), areDiagsSelfContained()), - IsQtApplication(Options.get("IsQtApplication", false)), - StringsMatchHeader(Options.get("StringsMatchHeader", "<utility>")) {} + IsQtApplication(Options.get("IsQtApplication", false)) {} void UseIntegerSignComparisonCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); Options.store(Opts, "IsQtApplication", IsQtApplication); - Options.store(Opts, "StringsMatchHeader", StringsMatchHeader); } void UseIntegerSignComparisonCheck::registerMatchers(MatchFinder *Finder) { @@ -38,57 +73,15 @@ void UseIntegerSignComparisonCheck::registerMatchers(MatchFinder *Finder) { // Flag all operators "==", "<=", ">=", "<", ">", "!=" // that are used between signed/unsigned const auto CompareOperator = - expr(binaryOperator(hasAnyOperatorName("==", "<=", ">=", "<", ">", "!="), - anyOf(allOf(hasLHS(SignedIntCastExpr), - hasRHS(UnSignedIntCastExpr)), - allOf(hasLHS(UnSignedIntCastExpr), - hasRHS(SignedIntCastExpr))))) + binaryOperator(hasAnyOperatorName("==", "<=", ">=", "<", ">", "!="), + hasOperands(SignedIntCastExpr, + UnSignedIntCastExpr), + unless(isInTemplateInstantiation())) .bind("intComparison"); Finder->addMatcher(CompareOperator, this); } -BindableMatcher<clang::Stmt> UseIntegerSignComparisonCheck::intCastExpression( - bool IsSigned, const std::string &CastBindName) const { - auto IntTypeExpr = expr(); - if (IsSigned) { - IntTypeExpr = expr(hasType(qualType(isInteger(), isSignedInteger()))); - } else { - IntTypeExpr = - expr(hasType(qualType(isInteger(), unless(isSignedInteger())))); - } - - const auto ImplicitCastExpr = - implicitCastExpr(hasSourceExpression(IntTypeExpr)).bind(CastBindName); - - const auto CStyleCastExpr = cStyleCastExpr(has(ImplicitCastExpr)); - const auto StaticCastExpr = cxxStaticCastExpr(has(ImplicitCastExpr)); - const auto FunctionalCastExpr = cxxFunctionalCastExpr(has(ImplicitCastExpr)); - - return traverse(TK_AsIs, expr(anyOf(ImplicitCastExpr, CStyleCastExpr, - StaticCastExpr, FunctionalCastExpr))); -} - -std::string -UseIntegerSignComparisonCheck::parseOpCode(BinaryOperator::Opcode code) const { - switch (code) { - case BO_LT: - return std::string("cmp_less"); - case BO_GT: - return std::string("cmp_greater"); - case BO_LE: - return std::string("cmp_less_equal"); - case BO_GE: - return std::string("cmp_greater_equal"); - case BO_EQ: - return std::string("cmp_equal"); - case BO_NE: - return std::string("cmp_not_equal"); - default: - return {}; - } -} - void UseIntegerSignComparisonCheck::registerPPCallbacks( const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { IncludeInserter.registerPreprocessor(PP); @@ -124,42 +117,59 @@ void UseIntegerSignComparisonCheck::check( if (LHS == nullptr || RHS == nullptr) return; - const StringRef LhsString(Lexer::getSourceText( - CharSourceRange::getTokenRange(LHS->getSourceRange()), - *Result.SourceManager, getLangOpts())); - - const StringRef RhsString(Lexer::getSourceText( - CharSourceRange::getTokenRange(RHS->getSourceRange()), - *Result.SourceManager, getLangOpts())); + const Expr *ExplicitLHS = nullptr; + const Expr *ExplicitRHS = nullptr; + StringRef ExplicitLhsString, ExplicitLhsRhsString; - DiagnosticBuilder Diag = - diag(BinaryOp->getBeginLoc(), - "comparison between 'signed' and 'unsigned' integers"); + DiagnosticBuilder Diag = diag(BinaryOp->getBeginLoc(), "comparison between 'signed' and 'unsigned' integers"); + if (BinaryOp->getLHS() == SignedCastExpression) + { + ExplicitLHS = SignedCastExpression->isPartOfExplicitCast() ? SignedCastExpression : nullptr; + ExplicitRHS = UnSignedCastExpression->isPartOfExplicitCast() ? UnSignedCastExpression : nullptr; + } else { + ExplicitRHS = SignedCastExpression->isPartOfExplicitCast() ? SignedCastExpression : nullptr; + ExplicitLHS = UnSignedCastExpression->isPartOfExplicitCast() ? UnSignedCastExpression : nullptr; + } if (!(getLangOpts().CPlusPlus17 && IsQtApplication) && !getLangOpts().CPlusPlus20) return; std::string CmpNamespace; + std::string CmpHeader; if (getLangOpts().CPlusPlus20) { - CmpNamespace = std::string("std::") + parseOpCode(OpCode); + CmpNamespace = std::string("std::") + std::string(parseOpCode(OpCode)); + CmpHeader = std::string("<utility>"); } else if (getLangOpts().CPlusPlus17 && IsQtApplication) { - CmpNamespace = std::string("q20::") + parseOpCode(OpCode); + CmpNamespace = std::string("q20::") + std::string(parseOpCode(OpCode)); + CmpHeader = std::string("<QtCore/q20utility.h>"); } // Use qt-use-integer-sign-comparison when C++17 is available and only for Qt // apps. Prefer modernize-use-integer-sign-comparison when C++20 is available! - Diag << FixItHint::CreateReplacement( - CharSourceRange::getTokenRange(BinaryOp->getBeginLoc(), - BinaryOp->getEndLoc()), - StringRef(std::string(CmpNamespace) + std::string("(") + - std::string(LhsString) + std::string(", ") + - std::string(RhsString) + std::string(")"))); + if (ExplicitLHS) { + ExplicitLhsString = Lexer::getSourceText(CharSourceRange::getTokenRange(ExplicitLHS->IgnoreCasts()->getSourceRange()), *Result.SourceManager, getLangOpts()); + Diag << FixItHint::CreateReplacement(LHS->getSourceRange(), llvm::Twine(CmpNamespace + "(" + ExplicitLhsString).str()); + } else { + Diag << FixItHint::CreateInsertion(LHS->getBeginLoc(), + llvm::Twine(CmpNamespace + "(").str()); + } + Diag << FixItHint::CreateReplacement(BinaryOp->getOperatorLoc(), ", "); + if (ExplicitRHS) { + ExplicitLhsRhsString = Lexer::getSourceText(CharSourceRange::getTokenRange(ExplicitRHS->IgnoreCasts()->getSourceRange()), *Result.SourceManager, getLangOpts()); + Diag << FixItHint::CreateReplacement(RHS->getSourceRange(), llvm::Twine(ExplicitLhsRhsString + ")").str()); + } else { + Diag << FixItHint::CreateInsertion( + Lexer::getLocForEndOfToken( + Result.SourceManager->getSpellingLoc(RHS->getEndLoc()), 0, + *Result.SourceManager, Result.Context->getLangOpts()), + ")"); + } // If there is no include for cmp_{*} functions, we'll add it. Diag << IncludeInserter.createIncludeInsertion( Result.SourceManager->getFileID(BinaryOp->getBeginLoc()), - StringsMatchHeader); + CmpHeader); } } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h index 44668c0656072f..a49728564ab237 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h @@ -33,13 +33,8 @@ class UseIntegerSignComparisonCheck : public ClangTidyCheck { } private: - ast_matchers::internal::BindableMatcher<clang::Stmt> - intCastExpression(bool IsSigned, const std::string &CastBindName) const; - std::string parseOpCode(BinaryOperator::Opcode code) const; - utils::IncludeInserter IncludeInserter; bool IsQtApplication = false; - const StringRef StringsMatchHeader; }; } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/qt/CMakeLists.txt b/clang-tools-extra/clang-tidy/qt/CMakeLists.txt index 9b252515bba3e6..dc1be2c1aeea16 100644 --- a/clang-tools-extra/clang-tidy/qt/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/qt/CMakeLists.txt @@ -3,7 +3,7 @@ set(LLVM_LINK_COMPONENTS Support ) -add_clang_library(clangTidyQtModule +add_clang_library(clangTidyQtModule STATIC QtTidyModule.cpp LINK_LIBS diff --git a/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp b/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp index 3f1362129ca9b2..2f2008157a44c0 100644 --- a/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp @@ -28,8 +28,6 @@ class QtClangTidyModule : public ClangTidyModule { Opts["qt-integer-sign-comparison.IncludeStyle"] = "llvm"; Opts["qt-integer-sign-comparison.IsQtApplication"] = "true"; - Opts["qt-integer-sign-comparison.StringsMatchHeader"] = - "<QtCore/q20utility.h>"; return Options; } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 9aa602e9a6a989..8a8e4bbc676aef 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -126,11 +126,8 @@ New checks - New :doc:`modernize-use-integer-sign-comparison <clang-tidy/checks/modernize/use-integer-sign-comparison>` check. - Performs comparisons between signed and unsigned integer types - mathematically correct. If C++20 is supported a fix-it replaces - integers comparisons to ``std::cmp_equal``, ``std::cmp_not_equal``, - ``std::cmp_less``, ``std::cmp_greater``, ``std::cmp_less_equal`` and - ``std::cmp_greater_equal`` functions. + Replace comparisons between signed and unsigned integers with their safe + ``std::cmp_*`` alternative. - New :doc:`portability-template-virtual-member-function <clang-tidy/checks/portability/template-virtual-member-function>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst index e8edc646c8e2f4..fb35cbc54f3555 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst @@ -3,11 +3,8 @@ modernize-use-integer-sign-comparison ===================================== -Performs comparisons between signed and unsigned integer types -mathematically correct. If C++20 is supported a fix-it replaces -integers comparisons to ``std::cmp_equal``, ``std::cmp_not_equal``, -``std::cmp_less``, ``std::cmp_greater``, ``std::cmp_less_equal`` and -``std::cmp_greater_equal`` functions. +Replace comparisons between signed and unsigned integers with their safe +``std::cmp_*`` alternative. Examples of fixes created by the check: diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp index b580e2dfc6731d..e93ff4f9be8814 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp @@ -2,25 +2,31 @@ // The code that triggers the check #define MAX_MACRO(a, b) (a < b) ? b : a -namespace std { unsigned int FuncParameters(int bla) { unsigned int result; if (result == bla) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] -// CHECK-FIXES: if (std::cmp_equal(result, bla)) +// CHECK-FIXES: if (std::cmp_equal(result , bla)) return 1; } template <typename T> -void TemplateFuncParameters(T val) { +void TemplateFuncParameter(T val) { unsigned long uL = 0; if (val >= uL) return; -// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] -// CHECK-FIXES: if (std::cmp_greater_equal(val, uL)) +// CHECK-MESSAGES-NOT: warning: +} + +template <typename T1, typename T2> +int TemplateFuncParameters(T1 val1, T2 val2) { + if (val1 >= val2) + return 0; +// CHECK-MESSAGES-NOT: warning: + return 1; } int AllComparisons() { @@ -30,32 +36,32 @@ int AllComparisons() { int sVar = -42; short sArray[2] = {-1, -2}; - if (uVar < sVar) + if ((int)uVar < sVar) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] -// CHECK-FIXES: if (std::cmp_less(uVar, sVar)) +// CHECK-FIXES: if (std::cmp_less(uVar , sVar)) (uVar != sVar) ? uVar = sVar : sVar = uVar; // CHECK-MESSAGES: :[[@LINE-2]]:6: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] -// CHECK-FIXES: (std::cmp_not_equal(uVar, sVar)) ? uVar = sVar +// CHECK-FIXES: (std::cmp_not_equal(uVar , sVar)) ? uVar = sVar while (uArray[0] <= sArray[0]) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] -// CHECK-FIXES: while (std::cmp_less_equal(uArray[0], sArray[0])) +// CHECK-FIXES: while (std::cmp_less_equal(uArray[0] , sArray[0])) if (uArray[1] > sArray[1]) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] -// CHECK-FIXES: if (std::cmp_greater(uArray[1], sArray[1])) +// CHECK-FIXES: if (std::cmp_greater(uArray[1] , sArray[1])) MAX_MACRO(uVar, sArray[0]); // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] FuncParameters(uVar); - TemplateFuncParameters(sVar); + TemplateFuncParameter(sVar); + TemplateFuncParameters(uVar, sVar); return 0; } -} diff --git a/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp index bb9e691e7cb797..48aa35fa9e73f8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp @@ -2,25 +2,31 @@ // The code that triggers the check #define MAX_MACRO(a, b) (a < b) ? b : a -namespace std { unsigned int FuncParameters(int bla) { unsigned int result; if (result == bla) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] -// CHECK-FIXES: if (q20::cmp_equal(result, bla)) +// CHECK-FIXES: if (q20::cmp_equal(result , bla)) return 1; } template <typename T> -void TemplateFuncParameters(T val) { +void TemplateFuncParameter(T val) { unsigned long uL = 0; if (val >= uL) return; -// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] -// CHECK-FIXES: if (q20::cmp_greater_equal(val, uL)) +// CHECK-MESSAGES-NOT: warning: +} + +template <typename T1, typename T2> +int TemplateFuncParameters(T1 val1, T2 val2) { + if (val1 >= val2) + return 0; +// CHECK-MESSAGES-NOT: warning: + return 1; } int AllComparisons() { @@ -30,32 +36,32 @@ int AllComparisons() { int sVar = -42; short sArray[2] = {-1, -2}; - if (uVar < sVar) + if ((int)uVar < sVar) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] -// CHECK-FIXES: if (q20::cmp_less(uVar, sVar)) +// CHECK-FIXES: if (q20::cmp_less(uVar , sVar)) (uVar != sVar) ? uVar = sVar : sVar = uVar; // CHECK-MESSAGES: :[[@LINE-2]]:6: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] -// CHECK-FIXES: (q20::cmp_not_equal(uVar, sVar)) ? uVar = sVar +// CHECK-FIXES: (q20::cmp_not_equal(uVar , sVar)) ? uVar = sVar while (uArray[0] <= sArray[0]) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] -// CHECK-FIXES: while (q20::cmp_less_equal(uArray[0], sArray[0])) +// CHECK-FIXES: while (q20::cmp_less_equal(uArray[0] , sArray[0])) if (uArray[1] > sArray[1]) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] -// CHECK-FIXES: if (q20::cmp_greater(uArray[1], sArray[1])) +// CHECK-FIXES: if (q20::cmp_greater(uArray[1] , sArray[1])) MAX_MACRO(uVar, sArray[0]); // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] FuncParameters(uVar); - TemplateFuncParameters(sVar); + TemplateFuncParameter(sVar); + TemplateFuncParameters(uVar, sVar); return 0; } -} >From 0f320e4fea76fd73cbda9139d3567d30cf98278e Mon Sep 17 00:00:00 2001 From: Tatiana Borisova <tatiana.boris...@qt.io> Date: Wed, 30 Oct 2024 16:14:17 +0100 Subject: [PATCH 6/8] fixup! fixup! fixup! fixup! fixup! [clang-tidy] Create a check for signed and unsigned integers comparison --- .../UseIntegerSignComparisonCheck.cpp | 61 ++++++++++++------- .../modernize/use-integer-sign-comparison.rst | 8 +++ .../checks/qt/integer-sign-comparison.rst | 8 +-- 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp index 1d9014ad84702f..cd073f048cc629 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp @@ -15,11 +15,12 @@ using namespace clang::ast_matchers; using namespace clang::ast_matchers::internal; namespace clang::tidy::modernize { -static BindableMatcher<clang::Stmt> intCastExpression(bool IsSigned, - const std::string &CastBindName) { - auto IntTypeExpr = IsSigned - ? expr(hasType(hasCanonicalType(qualType(isInteger(), isSignedInteger())))) - : expr(hasType(hasCanonicalType(qualType(isInteger(), unless(isSignedInteger()))))); +static BindableMatcher<clang::Stmt> +intCastExpression(bool IsSigned, const std::string &CastBindName) { + auto IntTypeExpr = IsSigned ? expr(hasType(hasCanonicalType( + qualType(isInteger(), isSignedInteger())))) + : expr(hasType(hasCanonicalType(qualType( + isInteger(), unless(isSignedInteger()))))); const auto ImplicitCastExpr = implicitCastExpr(hasSourceExpression(IntTypeExpr)).bind(CastBindName); @@ -28,8 +29,8 @@ static BindableMatcher<clang::Stmt> intCastExpression(bool IsSigned, const auto StaticCastExpr = cxxStaticCastExpr(has(ImplicitCastExpr)); const auto FunctionalCastExpr = cxxFunctionalCastExpr(has(ImplicitCastExpr)); - return expr(anyOf(ImplicitCastExpr, CStyleCastExpr, - StaticCastExpr, FunctionalCastExpr)); + return expr(anyOf(ImplicitCastExpr, CStyleCastExpr, StaticCastExpr, + FunctionalCastExpr)); } static StringRef parseOpCode(BinaryOperator::Opcode Code) { @@ -74,8 +75,7 @@ void UseIntegerSignComparisonCheck::registerMatchers(MatchFinder *Finder) { // that are used between signed/unsigned const auto CompareOperator = binaryOperator(hasAnyOperatorName("==", "<=", ">=", "<", ">", "!="), - hasOperands(SignedIntCastExpr, - UnSignedIntCastExpr), + hasOperands(SignedIntCastExpr, UnSignedIntCastExpr), unless(isInTemplateInstantiation())) .bind("intComparison"); @@ -121,14 +121,23 @@ void UseIntegerSignComparisonCheck::check( const Expr *ExplicitRHS = nullptr; StringRef ExplicitLhsString, ExplicitLhsRhsString; - DiagnosticBuilder Diag = diag(BinaryOp->getBeginLoc(), "comparison between 'signed' and 'unsigned' integers"); - if (BinaryOp->getLHS() == SignedCastExpression) - { - ExplicitLHS = SignedCastExpression->isPartOfExplicitCast() ? SignedCastExpression : nullptr; - ExplicitRHS = UnSignedCastExpression->isPartOfExplicitCast() ? UnSignedCastExpression : nullptr; + DiagnosticBuilder Diag = + diag(BinaryOp->getBeginLoc(), + "comparison between 'signed' and 'unsigned' integers"); + if (BinaryOp->getLHS() == SignedCastExpression) { + ExplicitLHS = SignedCastExpression->isPartOfExplicitCast() + ? SignedCastExpression + : nullptr; + ExplicitRHS = UnSignedCastExpression->isPartOfExplicitCast() + ? UnSignedCastExpression + : nullptr; } else { - ExplicitRHS = SignedCastExpression->isPartOfExplicitCast() ? SignedCastExpression : nullptr; - ExplicitLHS = UnSignedCastExpression->isPartOfExplicitCast() ? UnSignedCastExpression : nullptr; + ExplicitRHS = SignedCastExpression->isPartOfExplicitCast() + ? SignedCastExpression + : nullptr; + ExplicitLHS = UnSignedCastExpression->isPartOfExplicitCast() + ? UnSignedCastExpression + : nullptr; } if (!(getLangOpts().CPlusPlus17 && IsQtApplication) && @@ -148,16 +157,25 @@ void UseIntegerSignComparisonCheck::check( // Use qt-use-integer-sign-comparison when C++17 is available and only for Qt // apps. Prefer modernize-use-integer-sign-comparison when C++20 is available! if (ExplicitLHS) { - ExplicitLhsString = Lexer::getSourceText(CharSourceRange::getTokenRange(ExplicitLHS->IgnoreCasts()->getSourceRange()), *Result.SourceManager, getLangOpts()); - Diag << FixItHint::CreateReplacement(LHS->getSourceRange(), llvm::Twine(CmpNamespace + "(" + ExplicitLhsString).str()); + ExplicitLhsString = + Lexer::getSourceText(CharSourceRange::getTokenRange( + ExplicitLHS->IgnoreCasts()->getSourceRange()), + *Result.SourceManager, getLangOpts()); + Diag << FixItHint::CreateReplacement( + LHS->getSourceRange(), + llvm::Twine(CmpNamespace + "(" + ExplicitLhsString).str()); } else { Diag << FixItHint::CreateInsertion(LHS->getBeginLoc(), llvm::Twine(CmpNamespace + "(").str()); } Diag << FixItHint::CreateReplacement(BinaryOp->getOperatorLoc(), ", "); if (ExplicitRHS) { - ExplicitLhsRhsString = Lexer::getSourceText(CharSourceRange::getTokenRange(ExplicitRHS->IgnoreCasts()->getSourceRange()), *Result.SourceManager, getLangOpts()); - Diag << FixItHint::CreateReplacement(RHS->getSourceRange(), llvm::Twine(ExplicitLhsRhsString + ")").str()); + ExplicitLhsRhsString = + Lexer::getSourceText(CharSourceRange::getTokenRange( + ExplicitRHS->IgnoreCasts()->getSourceRange()), + *Result.SourceManager, getLangOpts()); + Diag << FixItHint::CreateReplacement( + RHS->getSourceRange(), llvm::Twine(ExplicitLhsRhsString + ")").str()); } else { Diag << FixItHint::CreateInsertion( Lexer::getLocForEndOfToken( @@ -168,8 +186,7 @@ void UseIntegerSignComparisonCheck::check( // If there is no include for cmp_{*} functions, we'll add it. Diag << IncludeInserter.createIncludeInsertion( - Result.SourceManager->getFileID(BinaryOp->getBeginLoc()), - CmpHeader); + Result.SourceManager->getFileID(BinaryOp->getBeginLoc()), CmpHeader); } } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst index fb35cbc54f3555..b61a6c5a079e02 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst @@ -33,3 +33,11 @@ becomes return 1; } + +Options +------- + +.. option:: IncludeStyle + + A string specifying which include-style is used, `llvm` or `google`. + Default is `llvm`. diff --git a/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst index a91fe7f714d9b4..753cd952286844 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst @@ -55,14 +55,10 @@ Options .. option:: IncludeStyle - A string specifying which include-style is used, `llvm` or `google`. Default - is `llvm`. + A string specifying which include-style is used, `llvm` or `google`. + Default is `llvm`. .. option:: IsQtApplication When `true` (default `false`), then it is assumed that the code being analyzed is the Qt-based code. - -.. option:: StringsMatchHeader - A string specifying a include header file to be added by fix-it. Default - is `<utility>`. >From be56a624cb600cc76bf4f92ff157a98cd43db3d0 Mon Sep 17 00:00:00 2001 From: Tatiana Borisova <tatiana.boris...@qt.io> Date: Wed, 30 Oct 2024 16:19:40 +0100 Subject: [PATCH 7/8] fixup! fixup! fixup! fixup! fixup! fixup! [clang-tidy] Create a check for signed and unsigned integers comparison --- .../docs/clang-tidy/checks/qt/integer-sign-comparison.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst index 753cd952286844..7a6e0925beed08 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst @@ -60,5 +60,5 @@ Options .. option:: IsQtApplication - When `true` (default `false`), then it is assumed that the code being analyzed - is the Qt-based code. + When `true`, then it is assumed that the code being analyzed is the Qt-based code. + Default is `false`. >From ce5486b66d3daeea70549551648ad8382d5ae7c0 Mon Sep 17 00:00:00 2001 From: Tatiana Borisova <tatiana.boris...@qt.io> Date: Sat, 2 Nov 2024 22:40:35 +0100 Subject: [PATCH 8/8] fixup! fixup! fixup! fixup! fixup! fixup! fixup! [clang-tidy] Create a check for signed and unsigned integers comparison --- .../UseIntegerSignComparisonCheck.cpp | 94 +++++++++---------- .../clang-tidy/qt/QtTidyModule.cpp | 6 +- clang-tools-extra/docs/ReleaseNotes.rst | 10 +- .../modernize/use-integer-sign-comparison.rst | 32 +++---- .../checks/qt/integer-sign-comparison.rst | 38 +++----- clang-tools-extra/docs/clang-tidy/index.rst | 2 +- .../modernize/use-integer-sign-comparison.cpp | 2 +- .../qt/qt-integer-sign-comparison.cpp | 6 +- 8 files changed, 85 insertions(+), 105 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp index cd073f048cc629..8f8fcdff465d67 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp @@ -17,10 +17,8 @@ using namespace clang::ast_matchers::internal; namespace clang::tidy::modernize { static BindableMatcher<clang::Stmt> intCastExpression(bool IsSigned, const std::string &CastBindName) { - auto IntTypeExpr = IsSigned ? expr(hasType(hasCanonicalType( - qualType(isInteger(), isSignedInteger())))) - : expr(hasType(hasCanonicalType(qualType( - isInteger(), unless(isSignedInteger()))))); + auto IntTypeExpr = expr(hasType(hasCanonicalType(qualType( + isInteger(), IsSigned ? isSignedInteger() : unless(isSignedInteger()))))); const auto ImplicitCastExpr = implicitCastExpr(hasSourceExpression(IntTypeExpr)).bind(CastBindName); @@ -117,28 +115,32 @@ void UseIntegerSignComparisonCheck::check( if (LHS == nullptr || RHS == nullptr) return; - const Expr *ExplicitLHS = nullptr; - const Expr *ExplicitRHS = nullptr; - StringRef ExplicitLhsString, ExplicitLhsRhsString; + const Expr *SubExprLHS = nullptr; + const Expr *SubExprRHS = nullptr; + SourceRange R1 = SourceRange(LHS->getBeginLoc()); + SourceRange R2 = SourceRange(BinaryOp->getOperatorLoc()); + + if (const auto *LHSCast = BinaryOp->getLHS() == SignedCastExpression + ? SignedCastExpression + : UnSignedCastExpression) { + if (LHSCast->isPartOfExplicitCast()) { + SubExprLHS = LHSCast->getSubExpr(); + R1 = SourceRange(LHS->getBeginLoc(), SubExprLHS->getBeginLoc()); + } + } + + if (const auto *RHSCast = BinaryOp->getLHS() == SignedCastExpression + ? UnSignedCastExpression + : SignedCastExpression) { + if (RHSCast->isPartOfExplicitCast()) { + SubExprRHS = RHSCast->getSubExpr(); + R2.setEnd(SubExprRHS->getBeginLoc()); + } + } DiagnosticBuilder Diag = diag(BinaryOp->getBeginLoc(), "comparison between 'signed' and 'unsigned' integers"); - if (BinaryOp->getLHS() == SignedCastExpression) { - ExplicitLHS = SignedCastExpression->isPartOfExplicitCast() - ? SignedCastExpression - : nullptr; - ExplicitRHS = UnSignedCastExpression->isPartOfExplicitCast() - ? UnSignedCastExpression - : nullptr; - } else { - ExplicitRHS = SignedCastExpression->isPartOfExplicitCast() - ? SignedCastExpression - : nullptr; - ExplicitLHS = UnSignedCastExpression->isPartOfExplicitCast() - ? UnSignedCastExpression - : nullptr; - } if (!(getLangOpts().CPlusPlus17 && IsQtApplication) && !getLangOpts().CPlusPlus20) @@ -147,42 +149,40 @@ void UseIntegerSignComparisonCheck::check( std::string CmpNamespace; std::string CmpHeader; if (getLangOpts().CPlusPlus20) { - CmpNamespace = std::string("std::") + std::string(parseOpCode(OpCode)); - CmpHeader = std::string("<utility>"); + CmpNamespace = llvm::Twine("std::" + parseOpCode(OpCode)).str(); + CmpHeader = "<utility>"; } else if (getLangOpts().CPlusPlus17 && IsQtApplication) { - CmpNamespace = std::string("q20::") + std::string(parseOpCode(OpCode)); - CmpHeader = std::string("<QtCore/q20utility.h>"); + CmpNamespace = llvm::Twine("q20::" + parseOpCode(OpCode)).str(); + CmpHeader = "<QtCore/q20utility.h>"; } // Use qt-use-integer-sign-comparison when C++17 is available and only for Qt // apps. Prefer modernize-use-integer-sign-comparison when C++20 is available! - if (ExplicitLHS) { - ExplicitLhsString = + if (SubExprLHS) { + StringRef ExplicitLhsString = Lexer::getSourceText(CharSourceRange::getTokenRange( - ExplicitLHS->IgnoreCasts()->getSourceRange()), + SubExprLHS->IgnoreCasts()->getSourceRange()), *Result.SourceManager, getLangOpts()); Diag << FixItHint::CreateReplacement( - LHS->getSourceRange(), - llvm::Twine(CmpNamespace + "(" + ExplicitLhsString).str()); + R1, llvm::Twine(CmpNamespace + "(" + ExplicitLhsString).str()); } else { - Diag << FixItHint::CreateInsertion(LHS->getBeginLoc(), + Diag << FixItHint::CreateInsertion(R1.getBegin(), llvm::Twine(CmpNamespace + "(").str()); } - Diag << FixItHint::CreateReplacement(BinaryOp->getOperatorLoc(), ", "); - if (ExplicitRHS) { - ExplicitLhsRhsString = - Lexer::getSourceText(CharSourceRange::getTokenRange( - ExplicitRHS->IgnoreCasts()->getSourceRange()), - *Result.SourceManager, getLangOpts()); - Diag << FixItHint::CreateReplacement( - RHS->getSourceRange(), llvm::Twine(ExplicitLhsRhsString + ")").str()); - } else { - Diag << FixItHint::CreateInsertion( - Lexer::getLocForEndOfToken( - Result.SourceManager->getSpellingLoc(RHS->getEndLoc()), 0, - *Result.SourceManager, Result.Context->getLangOpts()), - ")"); - } + + StringRef ExplicitLhsRhsString = + SubExprRHS ? Lexer::getSourceText( + CharSourceRange::getTokenRange( + SubExprRHS->IgnoreCasts()->getSourceRange()), + *Result.SourceManager, getLangOpts()) + : ""; + Diag << FixItHint::CreateReplacement( + R2, llvm::Twine(", " + ExplicitLhsRhsString).str()); + Diag << FixItHint::CreateInsertion( + Lexer::getLocForEndOfToken( + Result.SourceManager->getSpellingLoc(RHS->getEndLoc()), 0, + *Result.SourceManager, Result.Context->getLangOpts()), + ")"); // If there is no include for cmp_{*} functions, we'll add it. Diag << IncludeInserter.createIncludeInsertion( diff --git a/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp b/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp index 2f2008157a44c0..2aabe9ed427cc3 100644 --- a/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/qt/QtTidyModule.cpp @@ -14,7 +14,7 @@ namespace clang::tidy { namespace qt { -/// A module containing checks of the C++ Core Guidelines +/// A module containing checks of the QT class QtClangTidyModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { @@ -33,9 +33,9 @@ class QtClangTidyModule : public ClangTidyModule { } }; -// Register the LLVMTidyModule using this statically initialized variable. +// Register the QtClangTidyModule using this statically initialized variable. static ClangTidyModuleRegistry::Add<QtClangTidyModule> - X("qt-module", "Adds checks for the Qt framework Guidelines."); + X("qt-module", "Adds checks for the QT."); } // namespace qt diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 8a8e4bbc676aef..b57f63716f48b4 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -127,7 +127,7 @@ New checks <clang-tidy/checks/modernize/use-integer-sign-comparison>` check. Replace comparisons between signed and unsigned integers with their safe - ``std::cmp_*`` alternative. + C++20 ``std::cmp_*`` alternative, if available. - New :doc:`portability-template-virtual-member-function <clang-tidy/checks/portability/template-virtual-member-function>` check. @@ -146,11 +146,9 @@ New check aliases <clang-tidy/checks/qt/integer-sign-comparison>` to :doc:`modernize-use-integer-sign-comparison <clang-tidy/checks/modernize/use-integer-sign-comparison>` check. - If C++17 is supported, the fix-it replaces integers comparisons to - ``q20::cmp_equal``, ``q20::cmp_not_equal``, ``q20::cmp_less``, - ``q20::cmp_greater``, ``q20::cmp_less_equal`` and ``q20::cmp_greater_equal`` - functions. - The check assumes the analysed code is Qt-based code. + + Replace comparisons between signed and unsigned integers with their safe + C++17 ``q20::cmp_*`` or C++20 ``std::cmp_*`` alternatives, if available. Changes in existing checks ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst index b61a6c5a079e02..3fab41f7787285 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst @@ -4,35 +4,26 @@ modernize-use-integer-sign-comparison ===================================== Replace comparisons between signed and unsigned integers with their safe -``std::cmp_*`` alternative. +C++20 ``std::cmp_*`` alternative, if available. + Examples of fixes created by the check: .. code-block:: c++ - uint func(int bla) - { - uint result; - if (result == bla) - return 0; - - return 1; - } + uint func(int a, uint b) { + return a == b; + } becomes .. code-block:: c++ - #include <utility> - - uint func(int bla) - { - uint result; - if (std::cmp_equal(result, bla)) - return 0; + #include <utility> - return 1; - } + uint func(int a, uint b) { + return (std::cmp_equal(result, bla)) + } Options ------- @@ -41,3 +32,8 @@ Options A string specifying which include-style is used, `llvm` or `google`. Default is `llvm`. + +.. option:: IsQtApplication + + When `true`, it is assumed that the code being analyzed is using the Qt framework. + Default is `false`. diff --git a/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst index 7a6e0925beed08..fe35b7345f4210 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/qt/integer-sign-comparison.rst @@ -11,44 +11,30 @@ Examples of fixes created by the check: .. code-block:: c++ - uint func(int bla) - { - uint result; - if (result == bla) - return 0; - - return 1; - } + uint func(int a, uint b) { + return a == b; + } in C++17 becomes .. code-block:: c++ - <QtCore/q20utility.h> - - uint func(int bla) - { - uint result; - if (q20::cmp_equal(result, bla)) - return 0; + <QtCore/q20utility.h> - return 1; - } + uint func(int a, uint b) { + return (q20::cmp_equal(result, bla)) + } in C++20 becomes .. code-block:: c++ - #include <utility> + #include <utility> - uint func(int bla) - { - uint result; - if (std::cmp_equal(result, bla)) - return 0; + uint func(int a, uint b) { + return (std::cmp_equal(result, bla)) + } - return 1; - } Options ------- @@ -60,5 +46,5 @@ Options .. option:: IsQtApplication - When `true`, then it is assumed that the code being analyzed is the Qt-based code. + When `true`, it is assumed that the code being analyzed is using the Qt framework. Default is `false`. diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst index 9663ed03c8734d..e0fc8ab73a5931 100644 --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -84,7 +84,7 @@ Name prefix Description ``performance-`` Checks that target performance-related issues. ``portability-`` Checks that target portability-related issues that don't relate to any particular coding style. -``qt-`` Checks related to Qt framework. +``qt-`` Checks related to the Qt framework. ``readability-`` Checks that target readability-related issues that don't relate to any particular coding style. ``zircon-`` Checks related to Zircon kernel coding conventions. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp index e93ff4f9be8814..4626a7f3a8a3bc 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp @@ -4,7 +4,7 @@ #define MAX_MACRO(a, b) (a < b) ? b : a unsigned int FuncParameters(int bla) { - unsigned int result; + unsigned int result = 0; if (result == bla) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] diff --git a/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp index 48aa35fa9e73f8..07e977d5c1b2ee 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/qt/qt-integer-sign-comparison.cpp @@ -4,7 +4,7 @@ #define MAX_MACRO(a, b) (a < b) ? b : a unsigned int FuncParameters(int bla) { - unsigned int result; + unsigned int result = 0; if (result == bla) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] @@ -36,10 +36,10 @@ int AllComparisons() { int sVar = -42; short sArray[2] = {-1, -2}; - if ((int)uVar < sVar) + if (uVar < (unsigned int)sVar) return 0; // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [qt-integer-sign-comparison] -// CHECK-FIXES: if (q20::cmp_less(uVar , sVar)) +// CHECK-FIXES: if (q20::cmp_less(uVar , sVar)) (uVar != sVar) ? uVar = sVar : sVar = uVar; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits