diff options
Diffstat (limited to 'clang-tools-extra/clang-tidy')
259 files changed, 2586 insertions, 1582 deletions
diff --git a/clang-tools-extra/clang-tidy/.clang-format b/clang-tools-extra/clang-tidy/.clang-format index 5b50661..fe94ed1 100644 --- a/clang-tools-extra/clang-tidy/.clang-format +++ b/clang-tools-extra/clang-tidy/.clang-format @@ -1,3 +1,8 @@ BasedOnStyle: LLVM -QualifierAlignment: Left +InsertNewlineAtEOF: true +KeepEmptyLines: + AtEndOfFile: false + AtStartOfBlock: false + AtStartOfFile: false LineEnding: LF +QualifierAlignment: Left diff --git a/clang-tools-extra/clang-tidy/.clang-tidy b/clang-tools-extra/clang-tidy/.clang-tidy index 0c2f34b..70d5731 100644 --- a/clang-tools-extra/clang-tidy/.clang-tidy +++ b/clang-tools-extra/clang-tidy/.clang-tidy @@ -1,4 +1,6 @@ InheritParentConfig: true +HeaderFilterRegex: 'clang-tools-extra/clang-tidy' +ExcludeHeaderFilterRegex: 'include-cleaner|clang-query' Checks: > bugprone-*, -bugprone-assignment-in-if-condition, @@ -7,6 +9,12 @@ Checks: > -bugprone-narrowing-conversions, -bugprone-unchecked-optional-access, -bugprone-unused-return-value, + cppcoreguidelines-init-variables, + cppcoreguidelines-missing-std-forward, + cppcoreguidelines-rvalue-reference-param-not-moved, + cppcoreguidelines-virtual-class-destructor, + google-readability-casting, + misc-const-correctness, modernize-*, -modernize-avoid-c-arrays, -modernize-pass-by-value, @@ -15,7 +23,6 @@ Checks: > performance-*, -performance-enum-size, -performance-no-int-to-ptr, - -performance-unnecessary-value-param, readability-*, -readability-avoid-nested-conditional-operator, -readability-braces-around-statements, @@ -30,8 +37,7 @@ Checks: > -readability-qualified-auto, -readability-simplify-boolean-expr, -readability-static-definition-in-anonymous-namespace, - -readability-suspicious-call-argument, - -readability-use-anyofallof + -readability-suspicious-call-argument CheckOptions: - key: performance-move-const-arg.CheckTriviallyCopyableMove diff --git a/clang-tools-extra/clang-tidy/ClangTidy.cpp b/clang-tools-extra/clang-tidy/ClangTidy.cpp index 76243e9..4af328c 100644 --- a/clang-tools-extra/clang-tidy/ClangTidy.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidy.cpp @@ -23,10 +23,10 @@ #include "clang-tidy-config.h" #include "clang/AST/ASTConsumer.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/DiagnosticFrontend.h" #include "clang/Format/Format.h" #include "clang/Frontend/ASTConsumers.h" #include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/MultiplexConsumer.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Lex/Preprocessor.h" @@ -356,7 +356,7 @@ ClangTidyASTConsumerFactory::ClangTidyASTConsumerFactory( if (Context.canExperimentalCustomChecks() && custom::RegisterCustomChecks) custom::RegisterCustomChecks(Context.getOptions(), *CheckFactories); #endif - for (ClangTidyModuleRegistry::entry const E : + for (const ClangTidyModuleRegistry::entry E : ClangTidyModuleRegistry::entries()) { std::unique_ptr<ClangTidyModule> Module = E.instantiate(); Module->addCheckFactories(*CheckFactories); @@ -455,8 +455,8 @@ ClangTidyASTConsumerFactory::createASTConsumer( if (Context.canEnableModuleHeadersParsing() && Context.getLangOpts().Modules && OverlayFS != nullptr) { - auto ModuleExpander = - std::make_unique<ExpandModularHeadersPPCallbacks>(&Compiler, OverlayFS); + auto ModuleExpander = std::make_unique<ExpandModularHeadersPPCallbacks>( + &Compiler, *OverlayFS); ModuleExpanderPP = ModuleExpander->getPreprocessor(); PP->addPPCallbacks(std::move(ModuleExpander)); } diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp index 81a9f93..16a4d13 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -478,11 +478,10 @@ bool ClangTidyDiagnosticConsumer::passesLineFilter(StringRef FileName, if (FileName.ends_with(Filter.Name)) { if (Filter.LineRanges.empty()) return true; - for (const FileFilter::LineRange &Range : Filter.LineRanges) { - if (Range.first <= LineNumber && LineNumber <= Range.second) - return true; - } - return false; + return llvm::any_of( + Filter.LineRanges, [&](const FileFilter::LineRange &Range) { + return Range.first <= LineNumber && LineNumber <= Range.second; + }); } } return false; @@ -527,7 +526,8 @@ void ClangTidyDiagnosticConsumer::forwardDiagnostic(const Diagnostic &Info) { Builder << Qualifiers::fromOpaqueValue(Info.getRawArg(Index)); break; case clang::DiagnosticsEngine::ak_qualtype: - Builder << QualType::getFromOpaquePtr((void *)Info.getRawArg(Index)); + Builder << QualType::getFromOpaquePtr( + reinterpret_cast<void *>(Info.getRawArg(Index))); break; case clang::DiagnosticsEngine::ak_declarationname: Builder << DeclarationName::getFromOpaqueInteger(Info.getRawArg(Index)); @@ -819,7 +819,6 @@ void ClangTidyDiagnosticConsumer::removeDuplicatedDiagnosticsOfAliasCheckers() { (*Inserted.first)->Message.Fix; if (CandidateFix != ExistingFix) { - // In case of a conflict, don't suggest any fix-it. ExistingError.Message.Fix.clear(); ExistingError.Notes.emplace_back( diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp index 487e5e2..9a4fc7a3 100644 --- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp +++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.cpp @@ -65,8 +65,7 @@ private: }; ExpandModularHeadersPPCallbacks::ExpandModularHeadersPPCallbacks( - CompilerInstance *CI, - IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS) + CompilerInstance *CI, llvm::vfs::OverlayFileSystem &OverlayFS) : Recorder(std::make_unique<FileRecorder>()), Compiler(*CI), InMemoryFs(new llvm::vfs::InMemoryFileSystem), Sources(Compiler.getSourceManager()), @@ -76,7 +75,7 @@ ExpandModularHeadersPPCallbacks::ExpandModularHeadersPPCallbacks( LangOpts(Compiler.getLangOpts()), HSOpts(Compiler.getHeaderSearchOpts()) { // Add a FileSystem containing the extra files needed in place of modular // headers. - OverlayFS->pushOverlay(InMemoryFs); + OverlayFS.pushOverlay(InMemoryFs); Diags.setSourceManager(&Sources); // FIXME: Investigate whatever is there better way to initialize DiagEngine diff --git a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h index 60cb01f..d72d021 100644 --- a/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h +++ b/clang-tools-extra/clang-tidy/ExpandModularHeadersPPCallbacks.h @@ -41,9 +41,8 @@ namespace tooling { /// non-modular way. class ExpandModularHeadersPPCallbacks : public PPCallbacks { public: - ExpandModularHeadersPPCallbacks( - CompilerInstance *CI, - IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS); + ExpandModularHeadersPPCallbacks(CompilerInstance *CI, + llvm::vfs::OverlayFileSystem &OverlayFS); ~ExpandModularHeadersPPCallbacks() override; /// Returns the preprocessor that provides callbacks for the whole @@ -138,7 +137,7 @@ private: std::unique_ptr<Preprocessor> PP; bool EnteredMainFile = false; bool StartedLexing = false; - Token CurrentToken; + Token CurrentToken = Token(); }; } // namespace tooling diff --git a/clang-tools-extra/clang-tidy/NoLintDirectiveHandler.cpp b/clang-tools-extra/clang-tidy/NoLintDirectiveHandler.cpp index a74ab00..b552ae8 100644 --- a/clang-tools-extra/clang-tidy/NoLintDirectiveHandler.cpp +++ b/clang-tools-extra/clang-tidy/NoLintDirectiveHandler.cpp @@ -19,7 +19,6 @@ #include "clang/Basic/SourceManager.h" #include "clang/Tooling/Core/Diagnostic.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" diff --git a/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp b/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp index 8aa23b8..ea98d01 100644 --- a/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp +++ b/clang-tools-extra/clang-tidy/altera/KernelNameRestrictionCheck.cpp @@ -74,7 +74,6 @@ bool KernelNameRestrictionPPCallbacks::fileNameIsRestricted( } void KernelNameRestrictionPPCallbacks::EndOfMainFile() { - // Check main file for restricted names. OptionalFileEntryRef Entry = SM.getFileEntryRefForID(SM.getMainFileID()); const StringRef FileName = llvm::sys::path::filename(Entry->getName()); diff --git a/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp index 2b1312c..d90305d 100644 --- a/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp +++ b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp @@ -63,9 +63,8 @@ void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) { const QualType StructFieldTy = StructField->getType(); if (StructFieldTy->isIncompleteType()) return; - const unsigned int StructFieldWidth = - (unsigned int)Result.Context->getTypeInfo(StructFieldTy.getTypePtr()) - .Width; + const unsigned int StructFieldWidth = static_cast<unsigned int>( + Result.Context->getTypeInfo(StructFieldTy.getTypePtr()).Width); FieldSizes.emplace_back(StructFieldWidth, StructField->getFieldIndex()); // FIXME: Recommend a reorganization of the struct (sort by StructField // size, largest to smallest). @@ -79,7 +78,7 @@ void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) { CharUnits::fromQuantity(std::max<clang::CharUnits::QuantityType>( std::ceil(static_cast<float>(TotalBitSize) / CharSize), 1)); const CharUnits MaxAlign = CharUnits::fromQuantity( - std::ceil((float)Struct->getMaxAlignment() / CharSize)); + std::ceil(static_cast<float>(Struct->getMaxAlignment()) / CharSize)); const CharUnits CurrAlign = Result.Context->getASTRecordLayout(Struct).getAlignment(); const CharUnits NewAlign = computeRecommendedAlignment(MinByteSize); @@ -99,8 +98,7 @@ void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) { diag(Struct->getLocation(), "accessing fields in struct %0 is inefficient due to padding; only " "needs %1 bytes but is using %2 bytes") - << Struct << (int)MinByteSize.getQuantity() - << (int)CurrSize.getQuantity() + << Struct << MinByteSize.getQuantity() << CurrSize.getQuantity() << FixItHint::CreateInsertion(Struct->getEndLoc().getLocWithOffset(1), " __attribute__((packed))"); diag(Struct->getLocation(), @@ -112,8 +110,7 @@ void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) { FixItHint FixIt; auto *Attribute = Struct->getAttr<AlignedAttr>(); - const std::string NewAlignQuantity = - std::to_string((int)NewAlign.getQuantity()); + const std::string NewAlignQuantity = std::to_string(NewAlign.getQuantity()); if (Attribute) { FixIt = FixItHint::CreateReplacement( Attribute->getRange(), @@ -130,7 +127,7 @@ void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) { diag(Struct->getLocation(), "accessing fields in struct %0 is inefficient due to poor alignment; " "currently aligned to %1 bytes, but recommended alignment is %2 bytes") - << Struct << (int)CurrAlign.getQuantity() << NewAlignQuantity << FixIt; + << Struct << CurrAlign.getQuantity() << NewAlignQuantity << FixIt; diag(Struct->getLocation(), "use \"__attribute__((aligned(%0)))\" to align struct %1 to %0 bytes", diff --git a/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp b/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp index b0cd4cd..c759e5b 100644 --- a/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp +++ b/clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp @@ -208,20 +208,22 @@ bool UnrollLoopsCheck::hasLargeNumIterations(const Stmt *Statement, return true; switch (Op->getOpcode()) { case (BO_AddAssign): - Iterations = std::ceil(float(EndValue - InitValue) / ConstantValue); + Iterations = + std::ceil(static_cast<float>(EndValue - InitValue) / ConstantValue); break; case (BO_SubAssign): - Iterations = std::ceil(float(InitValue - EndValue) / ConstantValue); + Iterations = + std::ceil(static_cast<float>(InitValue - EndValue) / ConstantValue); break; case (BO_MulAssign): - Iterations = - 1 + ((std::log((double)EndValue) - std::log((double)InitValue)) / - std::log((double)ConstantValue)); + Iterations = 1 + ((std::log(static_cast<double>(EndValue)) - + std::log(static_cast<double>(InitValue))) / + std::log(static_cast<double>(ConstantValue))); break; case (BO_DivAssign): - Iterations = - 1 + ((std::log((double)InitValue) - std::log((double)EndValue)) / - std::log((double)ConstantValue)); + Iterations = 1 + ((std::log(static_cast<double>(InitValue)) - + std::log(static_cast<double>(EndValue))) / + std::log(static_cast<double>(ConstantValue))); break; default: // All other operators are not handled; assume large bounds. diff --git a/clang-tools-extra/clang-tidy/android/CloexecCheck.cpp b/clang-tools-extra/clang-tidy/android/CloexecCheck.cpp index c046578..ff86fc5 100644 --- a/clang-tools-extra/clang-tidy/android/CloexecCheck.cpp +++ b/clang-tools-extra/clang-tidy/android/CloexecCheck.cpp @@ -36,7 +36,7 @@ static std::string buildFixMsgForStringFlag(const Expr *Arg, } void CloexecCheck::registerMatchersImpl( - MatchFinder *Finder, internal::Matcher<FunctionDecl> Function) { + MatchFinder *Finder, const internal::Matcher<FunctionDecl> &Function) { // We assume all the checked APIs are C functions. Finder->addMatcher( callExpr( diff --git a/clang-tools-extra/clang-tidy/android/CloexecCheck.h b/clang-tools-extra/clang-tidy/android/CloexecCheck.h index fc1accd..a6dcb57 100644 --- a/clang-tools-extra/clang-tidy/android/CloexecCheck.h +++ b/clang-tools-extra/clang-tidy/android/CloexecCheck.h @@ -29,9 +29,9 @@ public: : ClangTidyCheck(Name, Context) {} protected: - void - registerMatchersImpl(ast_matchers::MatchFinder *Finder, - ast_matchers::internal::Matcher<FunctionDecl> Function); + void registerMatchersImpl( + ast_matchers::MatchFinder *Finder, + const ast_matchers::internal::Matcher<FunctionDecl> &Function); /// Currently, we have three types of fixes. /// diff --git a/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp index 02fc8d8..970cbd9 100644 --- a/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp @@ -18,6 +18,7 @@ #include <initializer_list> #include <optional> #include <string> +#include <utility> // FixItHint - Let the docs script know that this class does provide fixits @@ -200,7 +201,6 @@ private: } // namespace utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { - ReplacerMap Results; static const Signature SingleSig = {{0}}; static const Signature TwoSig = {{0}, {2}}; @@ -217,11 +217,11 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { const auto AddFromStd = [&](llvm::IntrusiveRefCntPtr<UseRangesCheck::Replacer> Replacer, std::initializer_list<StringRef> Names) { - AddFrom(Replacer, Names, "std"); + AddFrom(std::move(Replacer), Names, "std"); }; const auto AddFromBoost = - [&](llvm::IntrusiveRefCntPtr<UseRangesCheck::Replacer> Replacer, + [&](const llvm::IntrusiveRefCntPtr<UseRangesCheck::Replacer> &Replacer, std::initializer_list< std::pair<StringRef, std::initializer_list<StringRef>>> NamespaceAndNames) { diff --git a/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp index c0a778a..ed30d01 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp @@ -81,14 +81,16 @@ static std::vector<std::pair<SourceLocation, StringRef>> getCommentsInRange(ASTContext *Ctx, CharSourceRange Range) { std::vector<std::pair<SourceLocation, StringRef>> Comments; auto &SM = Ctx->getSourceManager(); - std::pair<FileID, unsigned> BeginLoc = SM.getDecomposedLoc(Range.getBegin()), - EndLoc = SM.getDecomposedLoc(Range.getEnd()); + const std::pair<FileID, unsigned> BeginLoc = + SM.getDecomposedLoc(Range.getBegin()), + EndLoc = + SM.getDecomposedLoc(Range.getEnd()); if (BeginLoc.first != EndLoc.first) return Comments; bool Invalid = false; - StringRef Buffer = SM.getBufferData(BeginLoc.first, &Invalid); + const StringRef Buffer = SM.getBufferData(BeginLoc.first, &Invalid); if (Invalid) return Comments; @@ -106,7 +108,7 @@ getCommentsInRange(ASTContext *Ctx, CharSourceRange Range) { break; if (Tok.is(tok::comment)) { - std::pair<FileID, unsigned> CommentLoc = + const std::pair<FileID, unsigned> CommentLoc = SM.getDecomposedLoc(Tok.getLocation()); assert(CommentLoc.first == BeginLoc.first); Comments.emplace_back( @@ -125,7 +127,7 @@ static std::vector<std::pair<SourceLocation, StringRef>> getCommentsBeforeLoc(ASTContext *Ctx, SourceLocation Loc) { std::vector<std::pair<SourceLocation, StringRef>> Comments; while (Loc.isValid()) { - clang::Token Tok = utils::lexer::getPreviousToken( + const clang::Token Tok = utils::lexer::getPreviousToken( Loc, Ctx->getSourceManager(), Ctx->getLangOpts(), /*SkipComments=*/false); if (Tok.isNot(tok::comment)) @@ -142,11 +144,11 @@ getCommentsBeforeLoc(ASTContext *Ctx, SourceLocation Loc) { static bool isLikelyTypo(llvm::ArrayRef<ParmVarDecl *> Params, StringRef ArgName, unsigned ArgIndex) { - std::string ArgNameLowerStr = ArgName.lower(); - StringRef ArgNameLower = ArgNameLowerStr; + const std::string ArgNameLowerStr = ArgName.lower(); + const StringRef ArgNameLower = ArgNameLowerStr; // The threshold is arbitrary. - unsigned UpperBound = ((ArgName.size() + 2) / 3) + 1; - unsigned ThisED = ArgNameLower.edit_distance( + const unsigned UpperBound = ((ArgName.size() + 2) / 3) + 1; + const unsigned ThisED = ArgNameLower.edit_distance( Params[ArgIndex]->getIdentifier()->getName().lower(), /*AllowReplacements=*/true, UpperBound); if (ThisED >= UpperBound) @@ -155,7 +157,7 @@ static bool isLikelyTypo(llvm::ArrayRef<ParmVarDecl *> Params, for (unsigned I = 0, E = Params.size(); I != E; ++I) { if (I == ArgIndex) continue; - IdentifierInfo *II = Params[I]->getIdentifier(); + const IdentifierInfo *II = Params[I]->getIdentifier(); if (!II) continue; @@ -163,9 +165,9 @@ static bool isLikelyTypo(llvm::ArrayRef<ParmVarDecl *> Params, // Other parameters must be an edit distance at least Threshold more away // from this parameter. This gives us greater confidence that this is a // typo of this parameter and not one with a similar name. - unsigned OtherED = ArgNameLower.edit_distance(II->getName().lower(), - /*AllowReplacements=*/true, - ThisED + Threshold); + const unsigned OtherED = ArgNameLower.edit_distance( + II->getName().lower(), + /*AllowReplacements=*/true, ThisED + Threshold); if (OtherED < ThisED + Threshold) return false; } @@ -267,7 +269,8 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, return; Callee = Callee->getFirstDecl(); - unsigned NumArgs = std::min<unsigned>(Args.size(), Callee->getNumParams()); + const unsigned NumArgs = + std::min<unsigned>(Args.size(), Callee->getNumParams()); if ((NumArgs == 0) || (IgnoreSingleArgument && NumArgs == 1)) return; @@ -279,7 +282,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, for (unsigned I = 0; I < NumArgs; ++I) { const ParmVarDecl *PVD = Callee->getParamDecl(I); - IdentifierInfo *II = PVD->getIdentifier(); + const IdentifierInfo *II = PVD->getIdentifier(); if (!II) continue; if (FunctionDecl *Template = Callee->getTemplateInstantiationPattern()) { @@ -293,7 +296,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, } } - CharSourceRange BeforeArgument = + const CharSourceRange BeforeArgument = MakeFileCharRange(ArgBeginLoc, Args[I]->getBeginLoc()); ArgBeginLoc = Args[I]->getEndLoc(); @@ -302,7 +305,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, Comments = getCommentsInRange(Ctx, BeforeArgument); } else { // Fall back to parsing back from the start of the argument. - CharSourceRange ArgsRange = + const CharSourceRange ArgsRange = MakeFileCharRange(Args[I]->getBeginLoc(), Args[I]->getEndLoc()); Comments = getCommentsBeforeLoc(Ctx, ArgsRange.getBegin()); } @@ -312,7 +315,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, if (IdentRE.match(Comment.second, &Matches) && !sameName(Matches[2], II->getName(), StrictMode)) { { - DiagnosticBuilder Diag = + const DiagnosticBuilder Diag = diag(Comment.first, "argument name '%0' in comment does not " "match parameter name %1") << Matches[2] << II; @@ -332,9 +335,9 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, // If the argument comments are missing for literals add them. if (Comments.empty() && shouldAddComment(Args[I])) { - std::string ArgComment = + const std::string ArgComment = (llvm::Twine("/*") + II->getName() + "=*/").str(); - DiagnosticBuilder Diag = + const DiagnosticBuilder Diag = diag(Args[I]->getBeginLoc(), "argument comment missing for literal argument %0") << II diff --git a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp index 1700502..a29aa55 100644 --- a/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/AssertSideEffectCheck.cpp @@ -29,7 +29,7 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls, const Expr *E = &Node; if (const auto *Op = dyn_cast<UnaryOperator>(E)) { - UnaryOperator::Opcode OC = Op->getOpcode(); + const UnaryOperator::Opcode OC = Op->getOpcode(); return OC == UO_PostInc || OC == UO_PostDec || OC == UO_PreInc || OC == UO_PreDec; } @@ -44,7 +44,7 @@ AST_MATCHER_P2(Expr, hasSideEffect, bool, CheckFunctionCalls, if (MethodDecl->isConst()) return false; - OverloadedOperatorKind OpKind = OpCallExpr->getOperator(); + const OverloadedOperatorKind OpKind = OpCallExpr->getOperator(); return OpKind == OO_Equal || OpKind == OO_PlusEqual || OpKind == OO_MinusEqual || OpKind == OO_StarEqual || OpKind == OO_SlashEqual || OpKind == OO_AmpEqual || @@ -130,7 +130,7 @@ void AssertSideEffectCheck::check(const MatchFinder::MatchResult &Result) { StringRef AssertMacroName; while (Loc.isValid() && Loc.isMacroID()) { - StringRef MacroName = Lexer::getImmediateMacroName(Loc, SM, LangOpts); + const StringRef MacroName = Lexer::getImmediateMacroName(Loc, SM, LangOpts); Loc = SM.getImmediateMacroCallerLoc(Loc); // Check if this macro is an assert. diff --git a/clang-tools-extra/clang-tidy/bugprone/AssignmentInIfConditionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/AssignmentInIfConditionCheck.cpp index 2c88562..d5d8a29 100644 --- a/clang-tools-extra/clang-tidy/bugprone/AssignmentInIfConditionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/AssignmentInIfConditionCheck.cpp @@ -66,7 +66,7 @@ void AssignmentInIfConditionCheck::check( } void AssignmentInIfConditionCheck::report(const Expr *AssignmentExpr) { - SourceLocation OpLoc = + const SourceLocation OpLoc = isa<BinaryOperator>(AssignmentExpr) ? cast<BinaryOperator>(AssignmentExpr)->getOperatorLoc() : cast<CXXOperatorCallExpr>(AssignmentExpr)->getOperatorLoc(); diff --git a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp index e1d0538a..3e1188d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BadSignalToKillThreadCheck.cpp @@ -40,7 +40,7 @@ void BadSignalToKillThreadCheck::check(const MatchFinder::MatchResult &Result) { const Token &T = MI->tokens().back(); if (!T.isLiteral() || !T.getLiteralData()) return std::nullopt; - StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength()); + const StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength()); llvm::APInt IntValue; constexpr unsigned AutoSenseRadix = 0; diff --git a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp index 07bb081..4f33670 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BranchCloneCheck.cpp @@ -75,12 +75,9 @@ static bool isFallthroughSwitchBranch(const SwitchBranch &Branch) { if (!S) return true; - for (const Attr *A : S->getAttrs()) { - if (isa<FallThroughAttr>(A)) - return false; - } - - return true; + return llvm::all_of(S->getAttrs(), [](const Attr *A) { + return !isa<FallThroughAttr>(A); + }); } } Visitor; @@ -117,7 +114,6 @@ void BranchCloneCheck::registerMatchers(MatchFinder *Finder) { /// static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, const Stmt *Stmt2, bool IgnoreSideEffects) { - if (!Stmt1 || !Stmt2) return !Stmt1 && !Stmt2; @@ -281,8 +277,8 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, const auto *IntLit1 = cast<IntegerLiteral>(Stmt1); const auto *IntLit2 = cast<IntegerLiteral>(Stmt2); - llvm::APInt I1 = IntLit1->getValue(); - llvm::APInt I2 = IntLit2->getValue(); + const llvm::APInt I1 = IntLit1->getValue(); + const llvm::APInt I2 = IntLit2->getValue(); if (I1.getBitWidth() != I2.getBitWidth()) return false; return I1 == I2; @@ -352,7 +348,7 @@ void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) { } } - size_t N = Branches.size(); + const size_t N = Branches.size(); llvm::BitVector KnownAsClone(N); for (size_t I = 0; I + 1 < N; I++) { @@ -375,7 +371,7 @@ void BranchCloneCheck::check(const MatchFinder::MatchResult &Result) { // We report the first occurrence only when we find the second one. diag(Branches[I]->getBeginLoc(), "repeated branch body in conditional chain"); - SourceLocation End = + const SourceLocation End = Lexer::getLocForEndOfToken(Branches[I]->getEndLoc(), 0, *Result.SourceManager, getLangOpts()); if (End.isValid()) { diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index baea231..6859dc9 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -30,6 +30,7 @@ #include "DynamicStaticInitializersCheck.h" #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" +#include "ExceptionCopyConstructorThrowsCheck.h" #include "ExceptionEscapeCheck.h" #include "FloatLoopCounterCheck.h" #include "FoldInitTypeCheck.h" @@ -64,6 +65,7 @@ #include "ParentVirtualCallCheck.h" #include "PointerArithmeticOnPolymorphicObjectCheck.h" #include "PosixReturnCheck.h" +#include "RandomGeneratorSeedCheck.h" #include "RawMemoryCallOnNonTrivialTypeCheck.h" #include "RedundantBranchConditionCheck.h" #include "ReservedIdentifierCheck.h" @@ -155,6 +157,8 @@ public: CheckFactories.registerCheck<EasilySwappableParametersCheck>( "bugprone-easily-swappable-parameters"); CheckFactories.registerCheck<EmptyCatchCheck>("bugprone-empty-catch"); + CheckFactories.registerCheck<ExceptionCopyConstructorThrowsCheck>( + "bugprone-exception-copy-constructor-throws"); CheckFactories.registerCheck<ExceptionEscapeCheck>( "bugprone-exception-escape"); CheckFactories.registerCheck<FloatLoopCounterCheck>( @@ -227,6 +231,8 @@ public: CheckFactories.registerCheck<ParentVirtualCallCheck>( "bugprone-parent-virtual-call"); CheckFactories.registerCheck<PosixReturnCheck>("bugprone-posix-return"); + CheckFactories.registerCheck<RandomGeneratorSeedCheck>( + "bugprone-random-generator-seed"); CheckFactories.registerCheck<RawMemoryCallOnNonTrivialTypeCheck>( "bugprone-raw-memory-call-on-non-trivial-type"); CheckFactories.registerCheck<ReservedIdentifierCheck>( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index aacaa61..db1256d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -26,6 +26,7 @@ add_clang_library(clangTidyBugproneModule STATIC DynamicStaticInitializersCheck.cpp EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp + ExceptionCopyConstructorThrowsCheck.cpp ExceptionEscapeCheck.cpp FloatLoopCounterCheck.cpp FoldInitTypeCheck.cpp @@ -65,6 +66,7 @@ add_clang_library(clangTidyBugproneModule STATIC ParentVirtualCallCheck.cpp PointerArithmeticOnPolymorphicObjectCheck.cpp PosixReturnCheck.cpp + RandomGeneratorSeedCheck.cpp RawMemoryCallOnNonTrivialTypeCheck.cpp RedundantBranchConditionCheck.cpp ReservedIdentifierCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp index a376de5..6aed454 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/CapturingThisInMemberVariableCheck.cpp @@ -44,18 +44,17 @@ AST_MATCHER(CXXRecordDecl, correctHandleCaptureThisLambda) { if (Node.hasSimpleMoveAssignment()) return false; - for (const CXXConstructorDecl *C : Node.ctors()) { - if (C->isCopyOrMoveConstructor() && C->isDefaulted() && !C->isDeleted()) - return false; - } - for (const CXXMethodDecl *M : Node.methods()) { - if (M->isCopyAssignmentOperator()) - llvm::errs() << M->isDeleted() << "\n"; - if (M->isCopyAssignmentOperator() && M->isDefaulted() && !M->isDeleted()) - return false; - if (M->isMoveAssignmentOperator() && M->isDefaulted() && !M->isDeleted()) - return false; - } + if (llvm::any_of(Node.ctors(), [](const CXXConstructorDecl *C) { + return C->isCopyOrMoveConstructor() && C->isDefaulted() && + !C->isDeleted(); + })) + return false; + if (llvm::any_of(Node.methods(), [](const CXXMethodDecl *M) { + return (M->isCopyAssignmentOperator() || + M->isMoveAssignmentOperator()) && + M->isDefaulted() && !M->isDeleted(); + })) + return false; // FIXME: find ways to identifier correct handle capture this lambda return true; } diff --git a/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.cpp index 3d3fc78..47acc21 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ChainedComparisonCheck.cpp @@ -11,7 +11,6 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" -#include <algorithm> using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp index 602b63e..9067f43 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ComparePointerToMemberVirtualFunctionCheck.cpp @@ -34,7 +34,6 @@ static constexpr llvm::StringLiteral ErrorMsg = void ComparePointerToMemberVirtualFunctionCheck::registerMatchers( MatchFinder *Finder) { - auto DirectMemberVirtualFunctionPointer = unaryOperator( allOf(hasOperatorName("&"), hasUnaryOperand(declRefExpr(to(cxxMethodDecl(isVirtual())))))); diff --git a/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.cpp index 76bcbbb..ccbc86a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/CopyConstructorInitCheck.cpp @@ -31,7 +31,7 @@ void CopyConstructorInitCheck::registerMatchers(MatchFinder *Finder) { void CopyConstructorInitCheck::check(const MatchFinder::MatchResult &Result) { const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor"); - std::string ParamName = Ctor->getParamDecl(0)->getNameAsString(); + const std::string ParamName = Ctor->getParamDecl(0)->getNameAsString(); // We want only one warning (and FixIt) for each ctor. std::string FixItInitList; @@ -40,7 +40,7 @@ void CopyConstructorInitCheck::check(const MatchFinder::MatchResult &Result) { bool HasWrittenInitializer = false; SmallVector<FixItHint, 2> SafeFixIts; for (const auto *Init : Ctor->inits()) { - bool CtorInitIsWritten = Init->isWritten(); + const bool CtorInitIsWritten = Init->isWritten(); HasWrittenInitializer = HasWrittenInitializer || CtorInitIsWritten; if (!Init->isBaseInitializer()) continue; diff --git a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp index 60f7be8..5ef72ea 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp @@ -116,9 +116,10 @@ void CrtpConstructorAccessibilityCheck::check( assert(DerivedTemplateParameter && "No template parameter corresponds to the derived class of the CRTP."); - bool NeedsFriend = !isDerivedParameterBefriended(CRTPDeclaration, - DerivedTemplateParameter) && - !isDerivedClassBefriended(CRTPDeclaration, DerivedRecord); + const bool NeedsFriend = + !isDerivedParameterBefriended(CRTPDeclaration, + DerivedTemplateParameter) && + !isDerivedClassBefriended(CRTPDeclaration, DerivedRecord); const FixItHint HintFriend = FixItHint::CreateInsertion( CRTPDeclaration->getBraceRange().getEnd(), diff --git a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp index 9f8e885..c95ad2b 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DanglingHandleCheck.cpp @@ -7,13 +7,11 @@ //===----------------------------------------------------------------------===// #include "DanglingHandleCheck.h" -#include "../utils/Matchers.h" #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" using namespace clang::ast_matchers; -using namespace clang::tidy::matchers; namespace clang::tidy::bugprone { @@ -31,7 +29,6 @@ handleFrom(const ast_matchers::internal::Matcher<RecordDecl> &IsAHandle, static ast_matchers::internal::Matcher<Stmt> handleFromTemporaryValue( const ast_matchers::internal::Matcher<RecordDecl> &IsAHandle) { - const auto TemporaryExpr = anyOf( cxxBindTemporaryExpr(), cxxFunctionalCastExpr( diff --git a/clang-tools-extra/clang-tidy/bugprone/DefaultOperatorNewOnOveralignedTypeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DefaultOperatorNewOnOveralignedTypeCheck.cpp index 0aafdfd..cb4f69a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DefaultOperatorNewOnOveralignedTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DefaultOperatorNewOnOveralignedTypeCheck.cpp @@ -26,7 +26,7 @@ void DefaultOperatorNewOnOveralignedTypeCheck::check( // Get the found 'new' expression. const auto *NewExpr = Result.Nodes.getNodeAs<CXXNewExpr>("new"); - QualType T = NewExpr->getAllocatedType(); + const QualType T = NewExpr->getAllocatedType(); // Dependent types do not have fixed alignment. if (T->isDependentType()) return; @@ -35,25 +35,25 @@ void DefaultOperatorNewOnOveralignedTypeCheck::check( if (!D || !D->isCompleteDefinition()) return; - ASTContext &Context = D->getASTContext(); + const ASTContext &Context = D->getASTContext(); // Check if no alignment was specified for the type. if (!Context.isAlignmentRequired(T)) return; // The user-specified alignment (in bits). - unsigned SpecifiedAlignment = D->getMaxAlignment(); + const unsigned SpecifiedAlignment = D->getMaxAlignment(); // Double-check if no alignment was specified. if (!SpecifiedAlignment) return; // The alignment used by default 'operator new' (in bits). - unsigned DefaultNewAlignment = Context.getTargetInfo().getNewAlign(); + const unsigned DefaultNewAlignment = Context.getTargetInfo().getNewAlign(); - bool OverAligned = SpecifiedAlignment > DefaultNewAlignment; - bool HasDefaultOperatorNew = + const bool OverAligned = SpecifiedAlignment > DefaultNewAlignment; + const bool HasDefaultOperatorNew = !NewExpr->getOperatorNew() || NewExpr->getOperatorNew()->isImplicit(); - unsigned CharWidth = Context.getTargetInfo().getCharWidth(); + const unsigned CharWidth = Context.getTargetInfo().getCharWidth(); if (HasDefaultOperatorNew && OverAligned) diag(NewExpr->getBeginLoc(), "allocation function returns a pointer with alignment %0 but the " diff --git a/clang-tools-extra/clang-tidy/bugprone/DerivedMethodShadowingBaseMethodCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DerivedMethodShadowingBaseMethodCheck.cpp index 743e6cd..7c58676 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DerivedMethodShadowingBaseMethodCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DerivedMethodShadowingBaseMethodCheck.cpp @@ -65,7 +65,7 @@ AST_MATCHER(CXXMethodDecl, nameCollidesWithMethodInBase) { for (const auto &BaseMethod : CurrentRecord->methods()) { if (namesCollide(*BaseMethod, Node)) { - ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder); + const ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder); Builder->setBinding("base_method", clang::DynTypedNode::create(*BaseMethod)); return true; diff --git a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp index 4d0428e..48de7fb 100644 --- a/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/DynamicStaticInitializersCheck.cpp @@ -43,7 +43,7 @@ void DynamicStaticInitializersCheck::registerMatchers(MatchFinder *Finder) { void DynamicStaticInitializersCheck::check( const MatchFinder::MatchResult &Result) { const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var"); - SourceLocation Loc = Var->getLocation(); + const SourceLocation Loc = Var->getLocation(); if (!Loc.isValid() || !utils::isPresumedLocInHeaderFile( Loc, *Result.SourceManager, HeaderFileExtensions)) return; diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp index b4ee351..496f3e5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp @@ -417,7 +417,7 @@ struct MixData { void sanitize() { assert(Flags != MixFlags::Invalid && "sanitize() called on invalid bitvec"); - MixFlags CanonicalAndWorkaround = + const MixFlags CanonicalAndWorkaround = MixFlags::Canonical | MixFlags::WorkaroundDisableCanonicalEquivalence; if ((Flags & CanonicalAndWorkaround) == CanonicalAndWorkaround) { // A workaround for too eagerly equivalent canonical types was requested, @@ -483,7 +483,7 @@ struct MixData { if (CommonType.isNull()) return *this; - QualType NewCommonType = Func(CommonType); + const QualType NewCommonType = Func(CommonType); if (CreatedFromOneWayConversion) { MixData M{Flags, Conversion}; @@ -761,7 +761,7 @@ calculateMixability(const TheCheck &Check, QualType LType, QualType RType, return {MixFlags::None}; } - MixData UnqualifiedMixability = + const MixData UnqualifiedMixability = calculateMixability(Check, LType.getLocalUnqualifiedType(), RType.getLocalUnqualifiedType(), Ctx, ImplicitMode) .withCommonTypeTransformed([&AdditionalQuals, &Ctx](QualType QT) { @@ -813,7 +813,7 @@ calculateMixability(const TheCheck &Check, QualType LType, QualType RType, if (ImplicitMode > ImplicitConversionModellingMode::None) { LLVM_DEBUG(llvm::dbgs() << "--- calculateMixability. Start implicit...\n"); - MixData MixLTR = + const MixData MixLTR = approximateImplicitConversion(Check, LType, RType, Ctx, ImplicitMode); LLVM_DEBUG( if (hasFlag(MixLTR.Flags, MixFlags::ImplicitConversion)) llvm::dbgs() @@ -833,7 +833,7 @@ calculateMixability(const TheCheck &Check, QualType LType, QualType RType, // Otherwise if the invoker requested a full modelling, do the other // direction as well. - MixData MixRTL = + const MixData MixRTL = approximateImplicitConversion(Check, RType, LType, Ctx, ImplicitMode); LLVM_DEBUG( if (hasFlag(MixRTL.Flags, MixFlags::ImplicitConversion)) llvm::dbgs() @@ -868,7 +868,7 @@ calculateMixability(const TheCheck &Check, QualType LType, QualType RType, // If none of the previous logic found a match, try if Clang otherwise // believes the types to be the same. - QualType LCanonical = LType.getCanonicalType(); + const QualType LCanonical = LType.getCanonicalType(); if (LCanonical == RType.getCanonicalType()) { LLVM_DEBUG(llvm::dbgs() << "<<< calculateMixability. Same CanonicalType.\n"); @@ -983,9 +983,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From, // Numeric promotions and conversions. const auto *FromBuiltin = WorkType->getAs<BuiltinType>(); const auto *ToBuiltin = To->getAs<BuiltinType>(); - bool FromNumeric = FromBuiltin && (FromBuiltin->isIntegerType() || - FromBuiltin->isFloatingType()); - bool ToNumeric = + const bool FromNumeric = FromBuiltin && (FromBuiltin->isIntegerType() || + FromBuiltin->isFloatingType()); + const bool ToNumeric = ToBuiltin && (ToBuiltin->isIntegerType() || ToBuiltin->isFloatingType()); if (FromNumeric && ToNumeric) { // If both are integral types, the numeric conversion is performed. @@ -1150,9 +1150,9 @@ public: continue; } - bool BestConversionHasImplicit = + const bool BestConversionHasImplicit = hasFlag(BestConversion->Flags, MixFlags::ImplicitConversion); - bool ThisConversionHasImplicit = + const bool ThisConversionHasImplicit = hasFlag(Prepared.Flags, MixFlags::ImplicitConversion); if (!BestConversionHasImplicit && ThisConversionHasImplicit) // This is a worse conversion, because a better one was found earlier. @@ -1221,7 +1221,7 @@ tryConversionOperators(const TheCheck &Check, const CXXRecordDecl *RD, if (std::optional<UserDefinedConversionSelector::PreparedConversion> SelectedConversion = ConversionSet()) { - CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD); + const CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD); ConversionSequence Result{RecordType, ToType}; // The conversion from the operator call's return type to ToType was @@ -1272,7 +1272,7 @@ tryConvertingConstructors(const TheCheck &Check, QualType FromType, if (std::optional<UserDefinedConversionSelector::PreparedConversion> SelectedConversion = ConversionSet()) { - CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD); + const CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD); ConversionSequence Result{FromType, RecordType}; Result.AfterFirstStandard = SelectedConversion->Seq.AfterFirstStandard; @@ -1385,7 +1385,7 @@ approximateImplicitConversion(const TheCheck &Check, QualType LType, LLVM_DEBUG( llvm::dbgs() << "--- approximateImplicitConversion. Try to find post-conversion.\n"); - MixData SecondStdConv = approximateImplicitConversion( + const MixData SecondStdConv = approximateImplicitConversion( Check, WorkType, RType, Ctx, ImplicitConversionModellingMode::OneWaySingleStandardOnly); if (SecondStdConv.indicatesMixability()) { @@ -1414,7 +1414,7 @@ approximateImplicitConversion(const TheCheck &Check, QualType LType, static MixableParameterRange modelMixingRange( const TheCheck &Check, const FunctionDecl *FD, std::size_t StartIndex, const filter::SimilarlyUsedParameterPairSuppressor &UsageBasedSuppressor) { - std::size_t NumParams = FD->getNumParams(); + const std::size_t NumParams = FD->getNumParams(); assert(StartIndex < NumParams && "out of bounds for start"); const ASTContext &Ctx = FD->getASTContext(); @@ -1424,7 +1424,7 @@ static MixableParameterRange modelMixingRange( for (std::size_t I = StartIndex + 1; I < NumParams; ++I) { const ParmVarDecl *Ith = FD->getParamDecl(I); - StringRef ParamName = Ith->getName(); + const StringRef ParamName = Ith->getName(); LLVM_DEBUG(llvm::dbgs() << "Check param #" << I << " '" << ParamName << "'...\n"); if (filter::isIgnoredParameter(Check, Ith)) { @@ -1432,7 +1432,7 @@ static MixableParameterRange modelMixingRange( break; } - StringRef PrevParamName = FD->getParamDecl(I - 1)->getName(); + const StringRef PrevParamName = FD->getParamDecl(I - 1)->getName(); if (!ParamName.empty() && !PrevParamName.empty() && filter::prefixSuffixCoverUnderThreshold( Check.NamePrefixSuffixSilenceDissimilarityThreshold, PrevParamName, @@ -1518,18 +1518,18 @@ static bool isIgnoredParameter(const TheCheck &Check, const ParmVarDecl *Node) { if (!Node->getIdentifier()) return llvm::is_contained(Check.IgnoredParameterNames, "\"\""); - StringRef NodeName = Node->getName(); + const StringRef NodeName = Node->getName(); if (llvm::is_contained(Check.IgnoredParameterNames, NodeName)) { LLVM_DEBUG(llvm::dbgs() << "\tName ignored.\n"); return true; } - StringRef NodeTypeName = [Node] { + const StringRef NodeTypeName = [Node] { const ASTContext &Ctx = Node->getASTContext(); const SourceManager &SM = Ctx.getSourceManager(); SourceLocation B = Node->getTypeSpecStartLoc(); SourceLocation E = Node->getTypeSpecEndLoc(); - LangOptions LO; + const LangOptions LO; LLVM_DEBUG(llvm::dbgs() << "\tType name code is '" << Lexer::getSourceText( @@ -1589,11 +1589,9 @@ static bool lazyMapOfSetsIntersectionExists(const MapTy &Map, const ElemTy &E1, if (E1Iterator == Map.end() || E2Iterator == Map.end()) return false; - for (const auto &E1SetElem : E1Iterator->second) - if (E2Iterator->second.contains(E1SetElem)) - return true; - - return false; + return llvm::any_of(E1Iterator->second, [&E2Iterator](const auto &E1SetElem) { + return E2Iterator->second.contains(E1SetElem); + }); } /// Implements the heuristic that marks two parameters related if there is @@ -1633,7 +1631,7 @@ public: RootSetInCurrentStackFrame = true; } - bool Ret = Base::TraverseStmt(S); + const bool Ret = Base::TraverseStmt(S); if (RootSetInCurrentStackFrame) CurrentExprOnlyTreeRoot = nullptr; @@ -1684,7 +1682,7 @@ public: continue; std::optional<unsigned> TargetIdx; - unsigned NumFnParams = CalledFn->getNumParams(); + const unsigned NumFnParams = CalledFn->getNumParams(); for (unsigned Idx = 0; Idx < NumFnParams; ++Idx) if (CalledFn->getParamDecl(Idx) == PassedToParam) TargetIdx.emplace(Idx); @@ -1837,16 +1835,16 @@ static void padStringAtBegin(SmallVectorImpl<char> &Str, std::size_t ToLen) { static bool isCommonPrefixWithoutSomeCharacters(std::size_t N, StringRef S1, StringRef S2) { assert(S1.size() >= N && S2.size() >= N); - StringRef S1Prefix = S1.take_front(S1.size() - N), - S2Prefix = S2.take_front(S2.size() - N); + const StringRef S1Prefix = S1.take_front(S1.size() - N), + S2Prefix = S2.take_front(S2.size() - N); return S1Prefix == S2Prefix && !S1Prefix.empty(); } static bool isCommonSuffixWithoutSomeCharacters(std::size_t N, StringRef S1, StringRef S2) { assert(S1.size() >= N && S2.size() >= N); - StringRef S1Suffix = S1.take_back(S1.size() - N), - S2Suffix = S2.take_back(S2.size() - N); + const StringRef S1Suffix = S1.take_back(S1.size() - N), + S2Suffix = S2.take_back(S2.size() - N); return S1Suffix == S2Suffix && !S1Suffix.empty(); } @@ -1858,7 +1856,7 @@ static bool prefixSuffixCoverUnderThreshold(std::size_t Threshold, return false; // Pad the two strings to the longer length. - std::size_t BiggerLength = std::max(Str1.size(), Str2.size()); + const std::size_t BiggerLength = std::max(Str1.size(), Str2.size()); if (BiggerLength <= Threshold) // If the length of the strings is still smaller than the threshold, they @@ -1980,7 +1978,7 @@ struct FormattedConversionSequence { // However, the parameter's defined type might not be what the implicit // conversion started with, e.g. if a typedef is found to convert. - std::string SeqBeginTypeStr = Conv.Begin.getAsString(PP); + const std::string SeqBeginTypeStr = Conv.Begin.getAsString(PP); std::string SeqEndTypeStr = Conv.End.getAsString(PP); if (StartTypeAsDiagnosed != SeqBeginTypeStr) { OS << " (as '" << SeqBeginTypeStr << "')"; @@ -1995,7 +1993,7 @@ struct FormattedConversionSequence { ++NumElementsAdded; } }; - for (QualType InvolvedType : Conv.getInvolvedTypesInSequence()) + for (const QualType InvolvedType : Conv.getInvolvedTypesInSequence()) // Print every type that's unique in the sequence into the diagnosis. AddType(InvolvedType.getAsString(PP)); @@ -2073,12 +2071,14 @@ public: if (CommonType.isNull() || CommonType == LHSType || CommonType == RHSType) return Base::operator()({LHSType, RHSType, {}}); - TypeAliasDiagnosticTuple ThreeTuple{LHSType, RHSType, CommonType}; + const TypeAliasDiagnosticTuple ThreeTuple{LHSType, RHSType, CommonType}; if (!Base::operator()(ThreeTuple)) return false; - bool AlreadySaidLHSAndCommonIsSame = calledWith({LHSType, CommonType, {}}); - bool AlreadySaidRHSAndCommonIsSame = calledWith({RHSType, CommonType, {}}); + const bool AlreadySaidLHSAndCommonIsSame = + calledWith({LHSType, CommonType, {}}); + const bool AlreadySaidRHSAndCommonIsSame = + calledWith({RHSType, CommonType, {}}); if (AlreadySaidLHSAndCommonIsSame && AlreadySaidRHSAndCommonIsSame) { // "SomeInt == int" && "SomeOtherInt == int" => "Common(SomeInt, // SomeOtherInt) == int", no need to diagnose it. Save the 3-tuple only @@ -2154,12 +2154,12 @@ void EasilySwappableParametersCheck::check( assert(FD); const PrintingPolicy &PP = FD->getASTContext().getPrintingPolicy(); - std::size_t NumParams = FD->getNumParams(); + const std::size_t NumParams = FD->getNumParams(); std::size_t MixableRangeStartIndex = 0; // Spawn one suppressor and if the user requested, gather information from // the AST for the parameters' usages. - filter::SimilarlyUsedParameterPairSuppressor UsageBasedSuppressor{ + const filter::SimilarlyUsedParameterPairSuppressor UsageBasedSuppressor{ FD, SuppressParametersUsedTogether}; LLVM_DEBUG(llvm::dbgs() << "Begin analysis of " << getName(FD) << " with " @@ -2182,11 +2182,13 @@ void EasilySwappableParametersCheck::check( continue; } - bool NeedsAnyTypeNote = llvm::any_of(R.Mixes, needsToPrintTypeInDiagnostic); - bool HasAnyImplicits = + const bool NeedsAnyTypeNote = + llvm::any_of(R.Mixes, needsToPrintTypeInDiagnostic); + const bool HasAnyImplicits = llvm::any_of(R.Mixes, needsToElaborateImplicitConversion); const ParmVarDecl *First = R.getFirstParam(), *Last = R.getLastParam(); - std::string FirstParamTypeAsWritten = First->getType().getAsString(PP); + const std::string FirstParamTypeAsWritten = + First->getType().getAsString(PP); { StringRef DiagText; @@ -2205,7 +2207,7 @@ void EasilySwappableParametersCheck::check( if (!NeedsAnyTypeNote) Diag << FirstParamTypeAsWritten; - CharSourceRange HighlightRange = CharSourceRange::getTokenRange( + const CharSourceRange HighlightRange = CharSourceRange::getTokenRange( First->getBeginLoc(), Last->getEndLoc()); Diag << HighlightRange; } @@ -2240,12 +2242,12 @@ void EasilySwappableParametersCheck::check( // emitted to a note diagnostic, so prepare it. const ParmVarDecl *LVar = M.First; const ParmVarDecl *RVar = M.Second; - QualType LType = LVar->getType(); - QualType RType = RVar->getType(); - QualType CommonType = M.commonUnderlyingType(); - std::string LTypeStr = LType.getAsString(PP); - std::string RTypeStr = RType.getAsString(PP); - std::string CommonTypeStr = CommonType.getAsString(PP); + const QualType LType = LVar->getType(); + const QualType RType = RVar->getType(); + const QualType CommonType = M.commonUnderlyingType(); + const std::string LTypeStr = LType.getAsString(PP); + const std::string RTypeStr = RType.getAsString(PP); + const std::string CommonTypeStr = CommonType.getAsString(PP); if (hasFlag(M.flags(), MixFlags::TypeAlias) && UniqueTypeAlias(LType, RType, CommonType)) { @@ -2274,8 +2276,9 @@ void EasilySwappableParametersCheck::check( if ((hasFlag(M.flags(), MixFlags::ReferenceBind) || hasFlag(M.flags(), MixFlags::Qualifiers)) && UniqueBindPower({LType, RType})) { - StringRef DiagText = "'%0' and '%1' parameters accept and bind the " - "same kind of values"; + const StringRef DiagText = + "'%0' and '%1' parameters accept and bind the " + "same kind of values"; diag(RVar->getOuterLocStart(), DiagText, DiagnosticIDs::Note) << LTypeStr << RTypeStr; } @@ -2286,8 +2289,8 @@ void EasilySwappableParametersCheck::check( M.leftToRightConversionSequence(); const model::ConversionSequence &RTL = M.rightToLeftConversionSequence(); - FormattedConversionSequence LTRFmt{PP, LTypeStr, LTR, RTypeStr}; - FormattedConversionSequence RTLFmt{PP, RTypeStr, RTL, LTypeStr}; + const FormattedConversionSequence LTRFmt{PP, LTypeStr, LTR, RTypeStr}; + const FormattedConversionSequence RTLFmt{PP, RTypeStr, RTL, LTypeStr}; StringRef DiagText = "'%0' and '%1' may be implicitly converted"; if (!LTRFmt.Trivial || !RTLFmt.Trivial) @@ -2302,7 +2305,7 @@ void EasilySwappableParametersCheck::check( Diag << LTRFmt.DiagnosticText << RTLFmt.DiagnosticText; } - StringRef ConversionFunctionDiagText = + const StringRef ConversionFunctionDiagText = "the implicit conversion involves the " "%select{|converting constructor|conversion operator}0 " "declared here"; diff --git a/clang-tools-extra/clang-tidy/bugprone/EmptyCatchCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EmptyCatchCheck.cpp index eebab84..5dd2f62 100644 --- a/clang-tools-extra/clang-tidy/bugprone/EmptyCatchCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/EmptyCatchCheck.cpp @@ -25,7 +25,7 @@ AST_MATCHER(CXXCatchStmt, isInMacro) { } AST_MATCHER_P(CXXCatchStmt, hasHandler, Matcher<Stmt>, InnerMatcher) { - Stmt *Handler = Node.getHandlerBlock(); + const Stmt *Handler = Node.getHandlerBlock(); if (!Handler) return false; return InnerMatcher.matches(*Handler, Finder, Builder); @@ -41,7 +41,7 @@ AST_MATCHER_P(CompoundStmt, hasAnyTextFromList, std::vector<llvm::StringRef>, return false; ASTContext &Context = Finder->getASTContext(); - SourceManager &SM = Context.getSourceManager(); + const SourceManager &SM = Context.getSourceManager(); StringRef Text = Lexer::getSourceText( CharSourceRange::getTokenRange(Node.getSourceRange()), SM, Context.getLangOpts()); diff --git a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionCopyConstructorThrowsCheck.cpp index 2225a90..7365845 100644 --- a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionCopyConstructorThrowsCheck.cpp @@ -6,15 +6,16 @@ // //===----------------------------------------------------------------------===// -#include "ThrownExceptionTypeCheck.h" +#include "ExceptionCopyConstructorThrowsCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" using namespace clang::ast_matchers; -namespace clang::tidy::cert { +namespace clang::tidy::bugprone { -void ThrownExceptionTypeCheck::registerMatchers(MatchFinder *Finder) { +void ExceptionCopyConstructorThrowsCheck::registerMatchers( + MatchFinder *Finder) { Finder->addMatcher( traverse( TK_AsIs, @@ -25,10 +26,11 @@ void ThrownExceptionTypeCheck::registerMatchers(MatchFinder *Finder) { this); } -void ThrownExceptionTypeCheck::check(const MatchFinder::MatchResult &Result) { +void ExceptionCopyConstructorThrowsCheck::check( + const MatchFinder::MatchResult &Result) { const auto *E = Result.Nodes.getNodeAs<Expr>("expr"); diag(E->getExprLoc(), "thrown exception type is not nothrow copy constructible"); } -} // namespace clang::tidy::cert +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.h b/clang-tools-extra/clang-tidy/bugprone/ExceptionCopyConstructorThrowsCheck.h index 41a51452..f1d7cca 100644 --- a/clang-tools-extra/clang-tidy/cert/ThrownExceptionTypeCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionCopyConstructorThrowsCheck.h @@ -6,20 +6,20 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_THROWNEXCEPTIONTYPECHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_THROWNEXCEPTIONTYPECHECK_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTIONCOPYCONSTRUCTORTHROWSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTIONCOPYCONSTRUCTORTHROWSCHECK_H #include "../ClangTidyCheck.h" -namespace clang::tidy::cert { +namespace clang::tidy::bugprone { /// Checks whether a thrown object is nothrow copy constructible. /// /// For the user-facing documentation see: -/// https://clang.llvm.org/extra/clang-tidy/checks/cert/err60-cpp.html -class ThrownExceptionTypeCheck : public ClangTidyCheck { +/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/exception-copy-constructor-throws.html +class ExceptionCopyConstructorThrowsCheck : public ClangTidyCheck { public: - ThrownExceptionTypeCheck(StringRef Name, ClangTidyContext *Context) + ExceptionCopyConstructorThrowsCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus; @@ -28,6 +28,6 @@ public: void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; -} // namespace clang::tidy::cert +} // namespace clang::tidy::bugprone -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_THROWNEXCEPTIONTYPECHECK_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTIONCOPYCONSTRUCTORTHROWSCHECK_H diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp index 837a86f..1cfb151 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp @@ -36,13 +36,22 @@ ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), RawFunctionsThatShouldNotThrow(Options.get( "FunctionsThatShouldNotThrow", "")), - RawIgnoredExceptions(Options.get("IgnoredExceptions", "")) { + RawIgnoredExceptions(Options.get("IgnoredExceptions", "")), + RawCheckedSwapFunctions( + Options.get("CheckedSwapFunctions", "swap,iter_swap,iter_move")), + CheckDestructors(Options.get("CheckDestructors", true)), + CheckMoveMemberFunctions(Options.get("CheckMoveMemberFunctions", true)), + CheckMain(Options.get("CheckMain", true)), + CheckNothrowFunctions(Options.get("CheckNothrowFunctions", true)) { llvm::SmallVector<StringRef, 8> FunctionsThatShouldNotThrowVec, - IgnoredExceptionsVec; + IgnoredExceptionsVec, CheckedSwapFunctionsVec; RawFunctionsThatShouldNotThrow.split(FunctionsThatShouldNotThrowVec, ",", -1, false); FunctionsThatShouldNotThrow.insert_range(FunctionsThatShouldNotThrowVec); + RawCheckedSwapFunctions.split(CheckedSwapFunctionsVec, ",", -1, false); + CheckedSwapFunctions.insert_range(CheckedSwapFunctionsVec); + llvm::StringSet<> IgnoredExceptions; RawIgnoredExceptions.split(IgnoredExceptionsVec, ",", -1, false); IgnoredExceptions.insert_range(IgnoredExceptionsVec); @@ -54,20 +63,34 @@ void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "FunctionsThatShouldNotThrow", RawFunctionsThatShouldNotThrow); Options.store(Opts, "IgnoredExceptions", RawIgnoredExceptions); + Options.store(Opts, "CheckedSwapFunctions", RawCheckedSwapFunctions); + Options.store(Opts, "CheckDestructors", CheckDestructors); + Options.store(Opts, "CheckMoveMemberFunctions", CheckMoveMemberFunctions); + Options.store(Opts, "CheckMain", CheckMain); + Options.store(Opts, "CheckNothrowFunctions", CheckNothrowFunctions); } void ExceptionEscapeCheck::registerMatchers(MatchFinder *Finder) { + auto MatchIf = [](bool Enabled, const auto &Matcher) { + const ast_matchers::internal::Matcher<FunctionDecl> Nothing = + unless(anything()); + return Enabled ? Matcher : Nothing; + }; Finder->addMatcher( functionDecl( isDefinition(), - anyOf(isNoThrow(), - allOf(anyOf(cxxDestructorDecl(), - cxxConstructorDecl(isMoveConstructor()), - cxxMethodDecl(isMoveAssignmentOperator()), isMain(), - allOf(hasAnyName("swap", "iter_swap", "iter_move"), - hasAtLeastOneParameter())), - unless(isExplicitThrow())), - isEnabled(FunctionsThatShouldNotThrow))) + anyOf( + MatchIf(CheckNothrowFunctions, isNoThrow()), + allOf(anyOf(MatchIf(CheckDestructors, cxxDestructorDecl()), + MatchIf( + CheckMoveMemberFunctions, + anyOf(cxxConstructorDecl(isMoveConstructor()), + cxxMethodDecl(isMoveAssignmentOperator()))), + MatchIf(CheckMain, isMain()), + allOf(isEnabled(CheckedSwapFunctions), + hasAtLeastOneParameter())), + unless(isExplicitThrow())), + isEnabled(FunctionsThatShouldNotThrow))) .bind("thrower"), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.h b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.h index 31d9e85..c3bf4a4 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.h @@ -35,8 +35,15 @@ public: private: StringRef RawFunctionsThatShouldNotThrow; StringRef RawIgnoredExceptions; + StringRef RawCheckedSwapFunctions; + + const bool CheckDestructors; + const bool CheckMoveMemberFunctions; + const bool CheckMain; + const bool CheckNothrowFunctions; llvm::StringSet<> FunctionsThatShouldNotThrow; + llvm::StringSet<> CheckedSwapFunctions; utils::ExceptionAnalyzer Tracer; }; diff --git a/clang-tools-extra/clang-tidy/bugprone/FloatLoopCounterCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/FloatLoopCounterCheck.cpp index adf2d2b..38a0234 100644 --- a/clang-tools-extra/clang-tidy/bugprone/FloatLoopCounterCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/FloatLoopCounterCheck.cpp @@ -31,6 +31,7 @@ void FloatLoopCounterCheck::registerMatchers(MatchFinder *Finder) { void FloatLoopCounterCheck::check(const MatchFinder::MatchResult &Result) { const auto *FS = Result.Nodes.getNodeAs<ForStmt>("for"); + assert(FS && "FS should not be null"); diag(FS->getInc()->getBeginLoc(), "loop induction expression should not have " "floating-point type") diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp index c3db8fa..11270e7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp @@ -46,7 +46,7 @@ void ForwardDeclarationNamespaceCheck::check( const MatchFinder::MatchResult &Result) { if (const auto *RecordDecl = Result.Nodes.getNodeAs<CXXRecordDecl>("record_decl")) { - StringRef DeclName = RecordDecl->getName(); + const StringRef DeclName = RecordDecl->getName(); if (RecordDecl->isThisDeclarationADefinition()) { DeclNameToDefinitions[DeclName].push_back(RecordDecl); } else { diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp index d372cbd..c1e66f2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp @@ -40,7 +40,7 @@ AST_MATCHER(QualType, isEnableIf) { if (CheckTemplate(BaseType->getAs<TemplateSpecializationType>())) return true; // Case: enable_if_t< >. if (const auto *TT = BaseType->getAs<TypedefType>()) - if (NestedNameSpecifier Q = TT->getQualifier(); + if (const NestedNameSpecifier Q = TT->getQualifier(); Q.getKind() == NestedNameSpecifier::Kind::Type) if (CheckTemplate(Q.getAsType()->getAs<TemplateSpecializationType>())) return true; // Case: enable_if< >::type. @@ -67,7 +67,7 @@ void ForwardingReferenceOverloadCheck::registerMatchers(MatchFinder *Finder) { unless(references(isConstQualified()))))) .bind("parm-var"); - DeclarationMatcher FindOverload = + const DeclarationMatcher FindOverload = cxxConstructorDecl( hasParameter(0, ForwardingRefParm), unless(isDeleted()), unless(hasAnyParameter( @@ -128,8 +128,9 @@ void ForwardingReferenceOverloadCheck::check( (OtherCtor->isCopyConstructor() ? EnabledCopy : EnabledMove) = true; } } - bool Copy = (!EnabledMove && !DisabledMove && !DisabledCopy) || EnabledCopy; - bool Move = !DisabledMove || EnabledMove; + const bool Copy = + (!EnabledMove && !DisabledMove && !DisabledCopy) || EnabledCopy; + const bool Move = !DisabledMove || EnabledMove; if (!Copy && !Move) return; diag(Ctor->getLocation(), diff --git a/clang-tools-extra/clang-tidy/bugprone/ImplicitWideningOfMultiplicationResultCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ImplicitWideningOfMultiplicationResultCheck.cpp index 2211a0b..634d54c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ImplicitWideningOfMultiplicationResultCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ImplicitWideningOfMultiplicationResultCheck.cpp @@ -71,18 +71,18 @@ ImplicitWideningOfMultiplicationResultCheck::includeStddefHeader( void ImplicitWideningOfMultiplicationResultCheck::handleImplicitCastExpr( const ImplicitCastExpr *ICE) { - ASTContext *Context = Result->Context; + const ASTContext *Context = Result->Context; const Expr *E = ICE->getSubExpr()->IgnoreParens(); - QualType Ty = ICE->getType(); - QualType ETy = E->getType(); + const QualType Ty = ICE->getType(); + const QualType ETy = E->getType(); assert(!ETy->isDependentType() && !Ty->isDependentType() && "Don't expect to ever get here in template Context."); // This must be a widening cast. Else we do not care. - unsigned SrcWidth = Context->getIntWidth(ETy); - unsigned TgtWidth = Context->getIntWidth(Ty); + const unsigned SrcWidth = Context->getIntWidth(ETy); + const unsigned TgtWidth = Context->getIntWidth(Ty); if (TgtWidth <= SrcWidth) return; @@ -92,7 +92,7 @@ void ImplicitWideningOfMultiplicationResultCheck::handleImplicitCastExpr( !ETy->isUnsignedIntegerType()) { if (const auto ConstExprResult = E->getIntegerConstantExpr(*Context)) { const auto TypeSize = Context->getTypeSize(ETy); - llvm::APSInt WidenedResult = ConstExprResult->extOrTrunc(TypeSize); + const llvm::APSInt WidenedResult = ConstExprResult->extOrTrunc(TypeSize); if (WidenedResult <= llvm::APSInt::getMaxValue(TypeSize, false) && WidenedResult >= llvm::APSInt::getMinValue(TypeSize, false)) return; @@ -168,7 +168,7 @@ void ImplicitWideningOfMultiplicationResultCheck::handleImplicitCastExpr( void ImplicitWideningOfMultiplicationResultCheck::handlePointerOffsetting( const Expr *E) { - ASTContext *Context = Result->Context; + const ASTContext *Context = Result->Context; // We are looking for a pointer offset operation, // with one hand being a pointer, and another one being an offset. @@ -191,19 +191,20 @@ void ImplicitWideningOfMultiplicationResultCheck::handlePointerOffsetting( IndexExpr = IndexExpr->IgnoreParens(); - QualType IndexExprType = IndexExpr->getType(); + const QualType IndexExprType = IndexExpr->getType(); // If the index expression's type is not known (i.e. we are in a template), // we can't do anything here. if (IndexExprType->isDependentType()) return; - QualType SSizeTy = Context->getPointerDiffType(); - QualType USizeTy = Context->getSizeType(); - QualType SizeTy = IndexExprType->isSignedIntegerType() ? SSizeTy : USizeTy; + const QualType SSizeTy = Context->getPointerDiffType(); + const QualType USizeTy = Context->getSizeType(); + const QualType SizeTy = + IndexExprType->isSignedIntegerType() ? SSizeTy : USizeTy; // FIXME: is there a way to actually get the QualType for size_t/ptrdiff_t? // Note that SizeTy.getAsString() will be unsigned long/..., NOT size_t! - StringRef TyAsString = + const StringRef TyAsString = IndexExprType->isSignedIntegerType() ? "ptrdiff_t" : "size_t"; // So, is size_t actually wider than the result of the multiplication? diff --git a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp index b0dd901..12fa365 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InaccurateEraseCheck.cpp @@ -43,7 +43,7 @@ void InaccurateEraseCheck::check(const MatchFinder::MatchResult &Result) { if (!Loc.isMacroID() && EndExpr) { const auto *AlgCall = Result.Nodes.getNodeAs<CallExpr>("alg"); - std::string ReplacementText = std::string(Lexer::getSourceText( + const std::string ReplacementText = std::string(Lexer::getSourceText( CharSourceRange::getTokenRange(EndExpr->getSourceRange()), *Result.SourceManager, getLangOpts())); const SourceLocation EndLoc = Lexer::getLocForEndOfToken( diff --git a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp index 9ce6d42..553c45c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp @@ -64,7 +64,6 @@ void IncDecInConditionsCheck::registerMatchers(MatchFinder *Finder) { } void IncDecInConditionsCheck::check(const MatchFinder::MatchResult &Result) { - SourceLocation ExprLoc; bool IsIncrementOp = false; diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp index 84a99c3..6181ac8 100644 --- a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp @@ -22,7 +22,7 @@ AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument, Node.getDefaultArgument().getArgument().isNull()) return false; - TypeLoc DefaultArgTypeLoc = + const TypeLoc DefaultArgTypeLoc = Node.getDefaultArgument().getTypeSourceInfo()->getTypeLoc(); return InnerMatcher.matches(DefaultArgTypeLoc, Finder, Builder); } @@ -51,7 +51,7 @@ void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) { return; const SourceManager &SM = *Result.SourceManager; - SourceLocation RAngleLoc = + const SourceLocation RAngleLoc = SM.getExpansionLoc(EnableIfSpecializationLoc->getRAngleLoc()); auto Diag = diag(EnableIf->getBeginLoc(), diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp index 1e516c1..6749c59 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp @@ -34,7 +34,7 @@ AST_MATCHER(FunctionType, typeHasNoReturnAttr) { } // namespace static Matcher<Stmt> loopEndingStmt(Matcher<Stmt> Internal) { - Matcher<QualType> IsNoReturnFunType = + const Matcher<QualType> IsNoReturnFunType = ignoringParens(functionType(typeHasNoReturnAttr())); Matcher<Decl> IsNoReturnDecl = anyOf(declHasNoReturnAttr(), functionDecl(hasType(IsNoReturnFunType)), @@ -119,14 +119,9 @@ static bool isAtLeastOneCondVarChanged(const Decl *Func, const Stmt *LoopStmt, if (isVarThatIsPossiblyChanged(Func, LoopStmt, Cond, Context)) return true; - for (const Stmt *Child : Cond->children()) { - if (!Child) - continue; - - if (isAtLeastOneCondVarChanged(Func, LoopStmt, Child, Context)) - return true; - } - return false; + return llvm::any_of(Cond->children(), [&](const Stmt *Child) { + return Child && isAtLeastOneCondVarChanged(Func, LoopStmt, Child, Context); + }); } /// Return the variable names in `Cond`. @@ -145,7 +140,7 @@ static std::string getCondVarNames(const Stmt *Cond) { if (!Child) continue; - std::string NewNames = getCondVarNames(Child); + const std::string NewNames = getCondVarNames(Child); if (!Result.empty() && !NewNames.empty()) Result += ", "; Result += NewNames; @@ -240,10 +235,9 @@ static bool hasStaticLocalVariable(const Stmt *Cond) { return true; } - for (const Stmt *Child : Cond->children()) - if (Child && hasStaticLocalVariable(Child)) - return true; - return false; + return llvm::any_of(Cond->children(), [](const Stmt *Child) { + return Child && hasStaticLocalVariable(Child); + }); } /// Tests if the loop condition `Cond` involves static local variables and @@ -332,7 +326,7 @@ void InfiniteLoopCheck::check(const MatchFinder::MatchResult &Result) { Result.Context)) return; - std::string CondVarNames = getCondVarNames(Cond); + const std::string CondVarNames = getCondVarNames(Cond); if (ShouldHaveConditionVariables && CondVarNames.empty()) return; diff --git a/clang-tools-extra/clang-tidy/bugprone/InvalidEnumDefaultInitializationCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InvalidEnumDefaultInitializationCheck.cpp index 18eb40f..f3e94b6 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InvalidEnumDefaultInitializationCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InvalidEnumDefaultInitializationCheck.cpp @@ -151,7 +151,7 @@ void InvalidEnumDefaultInitializationCheck::check( SourceLocation Loc = InitExpr->getExprLoc(); if (Loc.isInvalid()) { if (isa<ImplicitValueInitExpr, InitListExpr>(InitExpr)) { - DynTypedNodeList Parents = ACtx.getParents(*InitExpr); + const DynTypedNodeList Parents = ACtx.getParents(*InitExpr); if (Parents.empty()) return; @@ -170,7 +170,7 @@ void InvalidEnumDefaultInitializationCheck::check( // The expression may be implicitly generated for an initialization. // Search for a parent initialization list with valid source location. while (InitList->getExprLoc().isInvalid()) { - DynTypedNodeList Parents = ACtx.getParents(*InitList); + const DynTypedNodeList Parents = ACtx.getParents(*InitList); if (Parents.empty()) return; InitList = Parents[0].get<InitListExpr>(); diff --git a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp index fb73e89..1f666d2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp @@ -40,7 +40,7 @@ public: bool HasLine = false; for (const Token &T : MD.getMacroInfo()->tokens()) { if (T.is(tok::identifier)) { - StringRef IdentName = T.getIdentifierInfo()->getName(); + const StringRef IdentName = T.getIdentifierInfo()->getName(); if (IdentName == "__FILE__") { HasFile = true; } else if (IdentName == "__LINE__") { diff --git a/clang-tools-extra/clang-tidy/bugprone/MacroParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MacroParenthesesCheck.cpp index b16119d..6467fb5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MacroParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MacroParenthesesCheck.cpp @@ -152,7 +152,6 @@ void MacroParenthesesPPCallbacks::replacementList(const Token &MacroNameTok, void MacroParenthesesPPCallbacks::argument(const Token &MacroNameTok, const MacroInfo *MI) { - // Skip variable declaration. bool VarDecl = possibleVarDecl(MI, MI->tokens_begin()); diff --git a/clang-tools-extra/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp index 78a53d1..c79320f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp @@ -127,7 +127,7 @@ unsigned MacroRepeatedPPCallbacks::countArgumentExpansions( continue; } - IdentifierInfo *TII = T.getIdentifierInfo(); + const IdentifierInfo *TII = T.getIdentifierInfo(); // If not existent, skip it. if (TII == nullptr) continue; diff --git a/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp index d508e2a..f040235 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp @@ -52,8 +52,8 @@ static unsigned getMaxCalculationWidth(const ASTContext &Context, E = E->IgnoreParenImpCasts(); if (const auto *Bop = dyn_cast<BinaryOperator>(E)) { - unsigned LHSWidth = getMaxCalculationWidth(Context, Bop->getLHS()); - unsigned RHSWidth = getMaxCalculationWidth(Context, Bop->getRHS()); + const unsigned LHSWidth = getMaxCalculationWidth(Context, Bop->getLHS()); + const unsigned RHSWidth = getMaxCalculationWidth(Context, Bop->getRHS()); if (Bop->getOpcode() == BO_Mul) return LHSWidth + RHSWidth; if (Bop->getOpcode() == BO_Add) @@ -79,7 +79,7 @@ static unsigned getMaxCalculationWidth(const ASTContext &Context, if (Uop->getOpcode() == UO_Not) return 1024U; - QualType T = Uop->getType(); + const QualType T = Uop->getType(); return T->isIntegerType() ? Context.getIntWidth(T) : 1024U; } else if (const auto *I = dyn_cast<IntegerLiteral>(E)) { return I->getValue().getActiveBits(); @@ -190,10 +190,10 @@ void MisplacedWideningCastCheck::check(const MatchFinder::MatchResult &Result) { Calc->isTypeDependent() || Calc->isValueDependent()) return; - ASTContext &Context = *Result.Context; + const ASTContext &Context = *Result.Context; - QualType CastType = Cast->getType(); - QualType CalcType = Calc->getType(); + const QualType CastType = Cast->getType(); + const QualType CalcType = Calc->getType(); // Explicit truncation using cast. if (Context.getIntWidth(CastType) < Context.getIntWidth(CalcType)) diff --git a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp index 66559a0..e182df7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp @@ -21,7 +21,7 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee, const SourceManager &SM = Context.getSourceManager(); const LangOptions &LangOpts = Context.getLangOpts(); - CharSourceRange CallRange = + const CharSourceRange CallRange = Lexer::makeFileCharRange(CharSourceRange::getTokenRange( Callee->getBeginLoc(), Callee->getEndLoc()), SM, LangOpts); @@ -39,7 +39,7 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee, // std::move(). This will hopefully prevent erroneous replacements if the // code does unusual things (e.g. create an alias for std::move() in // another namespace). - NestedNameSpecifier NNS = Callee->getQualifier(); + const NestedNameSpecifier NNS = Callee->getQualifier(); switch (NNS.getKind()) { case NestedNameSpecifier::Kind::Null: // Called as "move" (i.e. presumably the code had a "using std::move;"). diff --git a/clang-tools-extra/clang-tidy/bugprone/MultiLevelImplicitPointerConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MultiLevelImplicitPointerConversionCheck.cpp index 2eff013..78f2017 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MultiLevelImplicitPointerConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MultiLevelImplicitPointerConversionCheck.cpp @@ -86,8 +86,9 @@ MultiLevelImplicitPointerConversionCheck::getCheckTraversalKind() const { void MultiLevelImplicitPointerConversionCheck::check( const MatchFinder::MatchResult &Result) { const auto *MatchedExpr = Result.Nodes.getNodeAs<ImplicitCastExpr>("expr"); - QualType Target = MatchedExpr->getType().getDesugaredType(*Result.Context); - QualType Source = + const QualType Target = + MatchedExpr->getType().getDesugaredType(*Result.Context); + const QualType Source = MatchedExpr->getSubExpr()->getType().getDesugaredType(*Result.Context); diag(MatchedExpr->getExprLoc(), "multilevel pointer conversion from %0 to " diff --git a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp index 17aea93..b81d2b4 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp @@ -51,7 +51,8 @@ namespace { AST_MATCHER_P(CXXTryStmt, hasHandlerFor, ast_matchers::internal::Matcher<QualType>, InnerMatcher) { - for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) { + const unsigned NH = Node.getNumHandlers(); + for (unsigned I = 0; I < NH; ++I) { const CXXCatchStmt *CatchS = Node.getHandler(I); // Check for generic catch handler (match anything). if (CatchS->getCaughtType().isNull()) @@ -66,7 +67,7 @@ AST_MATCHER_P(CXXTryStmt, hasHandlerFor, } AST_MATCHER(CXXNewExpr, mayThrow) { - FunctionDecl *OperatorNew = Node.getOperatorNew(); + const FunctionDecl *OperatorNew = Node.getOperatorNew(); if (!OperatorNew) return false; return !OperatorNew->getType()->castAs<FunctionProtoType>()->isNothrow(); diff --git a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp index 287ee95..501a82d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NarrowingConversionsCheck.cpp @@ -29,15 +29,15 @@ AST_MATCHER_P(QualType, hasAnyType, std::vector<StringRef>, Names) { if (Names.empty()) return false; - std::string Name = Node.getLocalUnqualifiedType().getAsString(); + const std::string Name = Node.getLocalUnqualifiedType().getAsString(); return llvm::is_contained(Names, Name); } AST_MATCHER(FieldDecl, hasIntBitwidth) { assert(Node.isBitField()); const ASTContext &Ctx = Node.getASTContext(); - unsigned IntBitWidth = Ctx.getIntWidth(Ctx.IntTy); - unsigned CurrentBitWidth = Node.getBitWidthValue(); + const unsigned IntBitWidth = Ctx.getIntWidth(Ctx.IntTy); + const unsigned CurrentBitWidth = Node.getBitWidthValue(); return IntBitWidth == CurrentBitWidth; } @@ -79,7 +79,7 @@ void NarrowingConversionsCheck::registerMatchers(MatchFinder *Finder) { const auto IsCeilFloorCallExpr = expr(callExpr(callee(functionDecl( hasAnyName("::ceil", "::std::ceil", "::floor", "::std::floor"))))); - std::vector<StringRef> IgnoreConversionFromTypesVec = + const std::vector<StringRef> IgnoreConversionFromTypesVec = utils::options::parseStringList(IgnoreConversionFromTypes); // We may want to exclude other types from the checks, such as `size_type` @@ -243,7 +243,7 @@ struct IntegerRange { static IntegerRange createFromType(const ASTContext &Context, const BuiltinType &T) { if (T.isFloatingPoint()) { - unsigned PrecisionBits = llvm::APFloatBase::semanticsPrecision( + const unsigned PrecisionBits = llvm::APFloatBase::semanticsPrecision( Context.getFloatTypeSemantics(T.desugar())); // Contrary to two's complement integer, floating point values are // symmetric and have the same number of positive and negative values. @@ -262,8 +262,8 @@ static IntegerRange createFromType(const ASTContext &Context, return {LowerValue, UpperValue}; } assert(T.isInteger() && "Unexpected builtin type"); - uint64_t TypeSize = Context.getTypeSize(&T); - bool IsUnsignedInteger = T.isUnsignedInteger(); + const uint64_t TypeSize = Context.getTypeSize(&T); + const bool IsUnsignedInteger = T.isUnsignedInteger(); return {llvm::APSInt::getMinValue(TypeSize, IsUnsignedInteger), llvm::APSInt::getMaxValue(TypeSize, IsUnsignedInteger)}; } @@ -271,15 +271,15 @@ static IntegerRange createFromType(const ASTContext &Context, static bool isWideEnoughToHold(const ASTContext &Context, const BuiltinType &FromType, const BuiltinType &ToType) { - IntegerRange FromIntegerRange = createFromType(Context, FromType); - IntegerRange ToIntegerRange = createFromType(Context, ToType); + const IntegerRange FromIntegerRange = createFromType(Context, FromType); + const IntegerRange ToIntegerRange = createFromType(Context, ToType); return ToIntegerRange.contains(FromIntegerRange); } static bool isWideEnoughToHold(const ASTContext &Context, const llvm::APSInt &IntegerConstant, const BuiltinType &ToType) { - IntegerRange ToIntegerRange = createFromType(Context, ToType); + const IntegerRange ToIntegerRange = createFromType(Context, ToType); return ToIntegerRange.contains(IntegerConstant); } @@ -289,13 +289,13 @@ static bool isWideEnoughToHold(const ASTContext &Context, static bool isFloatExactlyRepresentable(const ASTContext &Context, const llvm::APFloat &FloatConstant, const QualType &DestType) { - unsigned DestWidth = Context.getIntWidth(DestType); - bool DestSigned = DestType->isSignedIntegerOrEnumerationType(); + const unsigned DestWidth = Context.getIntWidth(DestType); + const bool DestSigned = DestType->isSignedIntegerOrEnumerationType(); llvm::APSInt Result = llvm::APSInt(DestWidth, !DestSigned); bool IsExact = false; - bool Overflows = FloatConstant.convertToInteger( - Result, llvm::APFloat::rmTowardZero, &IsExact) & - llvm::APFloat::opInvalidOp; + const bool Overflows = FloatConstant.convertToInteger( + Result, llvm::APFloat::rmTowardZero, &IsExact) & + llvm::APFloat::opInvalidOp; return !Overflows && IsExact; } @@ -321,8 +321,8 @@ bool NarrowingConversionsCheck::isWarningInhibitedByEquivalentSize( // With this option, we don't warn on conversions that have equivalent width // in bits. eg. uint32 <-> int32. if (!WarnOnEquivalentBitWidth) { - uint64_t FromTypeSize = Context.getTypeSize(&FromType); - uint64_t ToTypeSize = Context.getTypeSize(&ToType); + const uint64_t FromTypeSize = Context.getTypeSize(&FromType); + const uint64_t ToTypeSize = Context.getTypeSize(&ToType); if (FromTypeSize == ToTypeSize) { return true; } @@ -406,8 +406,8 @@ void NarrowingConversionsCheck::handleIntegralCast(const ASTContext &Context, // With this option, we don't warn on conversions that have equivalent width // in bits. eg. uint32 <-> int32. if (!WarnOnEquivalentBitWidth) { - uint64_t FromTypeSize = Context.getTypeSize(FromType); - uint64_t ToTypeSize = Context.getTypeSize(ToType); + const uint64_t FromTypeSize = Context.getTypeSize(FromType); + const uint64_t ToTypeSize = Context.getTypeSize(ToType); if (FromTypeSize == ToTypeSize) return; } @@ -583,7 +583,7 @@ void NarrowingConversionsCheck::handleImplicitCast( return; if (handleConditionalOperator(Context, Lhs, Rhs)) return; - SourceLocation SourceLoc = Lhs.getExprLoc(); + const SourceLocation SourceLoc = Lhs.getExprLoc(); switch (Cast.getCastKind()) { case CK_BooleanToSignedIntegral: handleBooleanToSignedIntegral(Context, SourceLoc, Lhs, Rhs); diff --git a/clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp index 067577f..127af27 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NonZeroEnumToBoolConversionCheck.cpp @@ -11,7 +11,6 @@ #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" -#include <algorithm> using namespace clang::ast_matchers; diff --git a/clang-tools-extra/clang-tidy/bugprone/NondeterministicPointerIterationOrderCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NondeterministicPointerIterationOrderCheck.cpp index abde115..fdb903a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NondeterministicPointerIterationOrderCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NondeterministicPointerIterationOrderCheck.cpp @@ -15,7 +15,6 @@ namespace clang::tidy::bugprone { void NondeterministicPointerIterationOrderCheck::registerMatchers( MatchFinder *Finder) { - auto LoopVariable = varDecl(hasType( qualType(hasCanonicalType(anyOf(referenceType(), pointerType()))))); @@ -60,7 +59,7 @@ void NondeterministicPointerIterationOrderCheck::check( TemplateArgs[0].getAsType()->isPointerType(); if (IsAlgoArgPointer) { - SourceRange R = RangeInit->getSourceRange(); + const SourceRange R = RangeInit->getSourceRange(); diag(R.getBegin(), "iteration of pointers is nondeterministic") << R; } } @@ -69,7 +68,7 @@ void NondeterministicPointerIterationOrderCheck::check( const auto *SortPointers = Result.Nodes.getNodeAs<Stmt>("sortsemantic"); if ((SortPointers) && !(SortPointers->getBeginLoc().isMacroID())) { - SourceRange R = SortPointers->getSourceRange(); + const SourceRange R = SortPointers->getSourceRange(); diag(R.getBegin(), "sorting pointers is nondeterministic") << R; } } diff --git a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp index 08fae7b..7198c1b 100644 --- a/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp @@ -120,18 +120,18 @@ static int getGivenLength(const MatchFinder::MatchResult &Result) { if (Result.Nodes.getNodeAs<Expr>(UnknownLengthName)) return 0; - if (int Length = + if (const int Length = getLength(Result.Nodes.getNodeAs<Expr>(WrongLengthExprName), Result)) return Length; - if (int Length = + if (const int Length = getLength(Result.Nodes.getNodeAs<Expr>(LengthExprName), Result)) return Length; // Special case, for example 'strlen("foo")'. if (const CallExpr *StrlenCE = getStrlenExpr(Result)) if (const Expr *Arg = StrlenCE->getArg(0)->IgnoreImpCasts()) - if (int ArgLength = getLength(Arg, Result)) + if (const int ArgLength = getLength(Arg, Result)) return ArgLength; return 0; @@ -174,9 +174,9 @@ static bool isKnownDest(const MatchFinder::MatchResult &Result) { // True if the capacity of the destination array is based on the given length, // therefore we assume that it cannot overflow (e.g. 'malloc(given_length + 1)' static bool isDestBasedOnGivenLength(const MatchFinder::MatchResult &Result) { - StringRef DestCapacityExprStr = + const StringRef DestCapacityExprStr = exprToStr(getDestCapacityExpr(Result), Result).trim(); - StringRef LengthExprStr = + const StringRef LengthExprStr = exprToStr(Result.Nodes.getNodeAs<Expr>(LengthExprName), Result).trim(); return !DestCapacityExprStr.empty() && !LengthExprStr.empty() && @@ -226,8 +226,9 @@ isGivenLengthEqualToSrcLength(const MatchFinder::MatchResult &Result) { if (isStringDataAndLength(Result)) return true; - int GivenLength = getGivenLength(Result); - int SrcLength = getLength(Result.Nodes.getNodeAs<Expr>(SrcExprName), Result); + const int GivenLength = getGivenLength(Result); + const int SrcLength = + getLength(Result.Nodes.getNodeAs<Expr>(SrcExprName), Result); if (GivenLength != 0 && SrcLength != 0 && GivenLength == SrcLength) return true; @@ -261,15 +262,15 @@ static bool isDestCapacityOverflows(const MatchFinder::MatchResult &Result) { return true; const Expr *DestCapacityExpr = getDestCapacityExpr(Result); - int DestCapacity = getLength(DestCapacityExpr, Result); - int GivenLength = getGivenLength(Result); + const int DestCapacity = getLength(DestCapacityExpr, Result); + const int GivenLength = getGivenLength(Result); if (GivenLength != 0 && DestCapacity != 0) return isGivenLengthEqualToSrcLength(Result) && DestCapacity == GivenLength; // Assume that the destination array's capacity cannot overflow if the // expression of the memory allocation contains '+ 1'. - StringRef DestCapacityExprStr = exprToStr(DestCapacityExpr, Result); + const StringRef DestCapacityExprStr = exprToStr(DestCapacityExpr, Result); if (DestCapacityExprStr.contains("+1") || DestCapacityExprStr.contains("+ 1")) return false; @@ -297,7 +298,7 @@ static void lengthExprHandle(const Expr *LengthExpr, // See whether we work with a macro. bool IsMacroDefinition = false; - StringRef LengthExprStr = exprToStr(LengthExpr, Result); + const StringRef LengthExprStr = exprToStr(LengthExpr, Result); Preprocessor::macro_iterator It = PP->macro_begin(); while (It != PP->macro_end() && !IsMacroDefinition) { if (It->first->getName() == LengthExprStr) @@ -309,7 +310,7 @@ static void lengthExprHandle(const Expr *LengthExpr, // Try to obtain an 'IntegerLiteral' and adjust it. if (!IsMacroDefinition) { if (const auto *LengthIL = dyn_cast<IntegerLiteral>(LengthExpr)) { - uint64_t NewLength = + const uint64_t NewLength = LengthIL->getValue().getZExtValue() + (LengthHandle == LengthHandleKind::Increase ? 1 : -1); @@ -347,7 +348,7 @@ static void lengthExprHandle(const Expr *LengthExpr, } // Try to inject the '+ 1'/'- 1' string. - bool NeedInnerParen = BO && BO->getOpcode() != BO_Add; + const bool NeedInnerParen = BO && BO->getOpcode() != BO_Add; if (NeedInnerParen) Diag << FixItHint::CreateInsertion(LengthExpr->getBeginLoc(), "("); @@ -384,8 +385,8 @@ static bool isDestExprFix(const MatchFinder::MatchResult &Result, if (!Dest) return false; - std::string TempTyStr = Dest->getType().getAsString(); - StringRef TyStr = TempTyStr; + const std::string TempTyStr = Dest->getType().getAsString(); + const StringRef TyStr = TempTyStr; if (TyStr.starts_with("char") || TyStr.starts_with("wchar_t")) return false; @@ -397,7 +398,7 @@ static bool isDestExprFix(const MatchFinder::MatchResult &Result, // increase the capacity by one to create space for the null terminator. static bool isDestCapacityFix(const MatchFinder::MatchResult &Result, DiagnosticBuilder &Diag) { - bool IsOverflows = isDestCapacityOverflows(Result); + const bool IsOverflows = isDestCapacityOverflows(Result); if (IsOverflows) if (const Expr *CapacityExpr = getDestCapacityExpr(Result)) lengthExprHandle(CapacityExpr, LengthHandleKind::Increase, Result, Diag); @@ -424,9 +425,9 @@ static void renameFunc(StringRef NewFuncName, const MatchFinder::MatchResult &Result, DiagnosticBuilder &Diag) { const auto *FunctionExpr = Result.Nodes.getNodeAs<CallExpr>(FunctionExprName); - int FuncNameLength = + const int FuncNameLength = FunctionExpr->getDirectCallee()->getIdentifier()->getLength(); - SourceRange FuncNameRange( + const SourceRange FuncNameRange( FunctionExpr->getBeginLoc(), FunctionExpr->getBeginLoc().getLocWithOffset(FuncNameLength - 1)); @@ -451,7 +452,7 @@ static void insertDestCapacityArg(bool IsOverflows, StringRef Name, const auto *FunctionExpr = Result.Nodes.getNodeAs<CallExpr>(FunctionExprName); SmallString<64> NewSecondArg; - if (int DestLength = getDestCapacity(Result)) { + if (const int DestLength = getDestCapacity(Result)) { NewSecondArg = Twine(IsOverflows ? DestLength + 1 : DestLength).str(); } else { NewSecondArg = @@ -470,12 +471,12 @@ static void insertNullTerminatorExpr(StringRef Name, const MatchFinder::MatchResult &Result, DiagnosticBuilder &Diag) { const auto *FunctionExpr = Result.Nodes.getNodeAs<CallExpr>(FunctionExprName); - int FuncLocStartColumn = Result.SourceManager->getPresumedColumnNumber( + const int FuncLocStartColumn = Result.SourceManager->getPresumedColumnNumber( FunctionExpr->getBeginLoc()); - SourceRange SpaceRange( + const SourceRange SpaceRange( FunctionExpr->getBeginLoc().getLocWithOffset(-FuncLocStartColumn + 1), FunctionExpr->getBeginLoc()); - StringRef SpaceBeforeStmtStr = Lexer::getSourceText( + const StringRef SpaceBeforeStmtStr = Lexer::getSourceText( CharSourceRange::getCharRange(SpaceRange), *Result.SourceManager, Result.Context->getLangOpts(), nullptr); @@ -717,10 +718,10 @@ void NotNullTerminatedResultCheck::registerMatchers(MatchFinder *Finder) { }; auto MatchCall = [=](CallContext CC) { - std::string CharHandlerFuncName = "::" + CC.Name.str(); + const std::string CharHandlerFuncName = "::" + CC.Name.str(); // Try to match with 'wchar_t' based function calls. - std::string WcharHandlerFuncName = + const std::string WcharHandlerFuncName = "::" + (CC.Name.starts_with("mem") ? "w" + CC.Name.str() : "wcs" + CC.Name.substr(3).str()); @@ -804,7 +805,8 @@ void NotNullTerminatedResultCheck::check( if (MI) { const auto &T = MI->tokens().back(); if (T.isLiteral() && T.getLiteralData()) { - StringRef ValueStr = StringRef(T.getLiteralData(), T.getLength()); + const StringRef ValueStr = + StringRef(T.getLiteralData(), T.getLength()); llvm::APInt IntValue; ValueStr.getAsInteger(10, IntValue); AreSafeFunctionsWanted = IntValue.getZExtValue(); @@ -819,7 +821,7 @@ void NotNullTerminatedResultCheck::check( UseSafeFunctions = *AreSafeFunctionsWanted; } - StringRef Name = FunctionExpr->getDirectCallee()->getName(); + const StringRef Name = FunctionExpr->getDirectCallee()->getName(); if (Name.starts_with("mem") || Name.starts_with("wmem")) memoryHandlerFunctionFix(Name, Result); else if (Name == "strerror_s") @@ -864,16 +866,16 @@ void NotNullTerminatedResultCheck::memoryHandlerFunctionFix( void NotNullTerminatedResultCheck::memcpyFix( StringRef Name, const MatchFinder::MatchResult &Result, DiagnosticBuilder &Diag) { - bool IsOverflows = isDestCapacityFix(Result, Diag); - bool IsDestFixed = isDestExprFix(Result, Diag); + const bool IsOverflows = isDestCapacityFix(Result, Diag); + const bool IsDestFixed = isDestExprFix(Result, Diag); - bool IsCopy = + const bool IsCopy = isGivenLengthEqualToSrcLength(Result) || isDestBasedOnGivenLength(Result); - bool IsSafe = UseSafeFunctions && IsOverflows && isKnownDest(Result) && - !isDestBasedOnGivenLength(Result); + const bool IsSafe = UseSafeFunctions && IsOverflows && isKnownDest(Result) && + !isDestBasedOnGivenLength(Result); - bool IsDestLengthNotRequired = + const bool IsDestLengthNotRequired = IsSafe && getLangOpts().CPlusPlus && Result.Nodes.getNodeAs<ArrayType>(DestArrayTyName) && !IsDestFixed; @@ -892,14 +894,14 @@ void NotNullTerminatedResultCheck::memcpyFix( void NotNullTerminatedResultCheck::memcpySFix( StringRef Name, const MatchFinder::MatchResult &Result, DiagnosticBuilder &Diag) { - bool IsOverflows = isDestCapacityFix(Result, Diag); - bool IsDestFixed = isDestExprFix(Result, Diag); + const bool IsOverflows = isDestCapacityFix(Result, Diag); + const bool IsDestFixed = isDestExprFix(Result, Diag); - bool RemoveDestLength = getLangOpts().CPlusPlus && - Result.Nodes.getNodeAs<ArrayType>(DestArrayTyName) && - !IsDestFixed; - bool IsCopy = isGivenLengthEqualToSrcLength(Result); - bool IsSafe = IsOverflows; + const bool RemoveDestLength = + getLangOpts().CPlusPlus && + Result.Nodes.getNodeAs<ArrayType>(DestArrayTyName) && !IsDestFixed; + const bool IsCopy = isGivenLengthEqualToSrcLength(Result); + const bool IsSafe = IsOverflows; renameMemcpy(Name, IsCopy, IsSafe, Result, Diag); @@ -932,7 +934,7 @@ void NotNullTerminatedResultCheck::memchrFix( Diag << CastRemoveFix; } - StringRef NewFuncName = (Name[0] != 'w') ? "strchr" : "wcschr"; + const StringRef NewFuncName = (Name[0] != 'w') ? "strchr" : "wcschr"; renameFunc(NewFuncName, Result, Diag); removeArg(2, Result, Diag); } @@ -940,7 +942,7 @@ void NotNullTerminatedResultCheck::memchrFix( void NotNullTerminatedResultCheck::memmoveFix( StringRef Name, const MatchFinder::MatchResult &Result, DiagnosticBuilder &Diag) const { - bool IsOverflows = isDestCapacityFix(Result, Diag); + const bool IsOverflows = isDestCapacityFix(Result, Diag); if (UseSafeFunctions && isKnownDest(Result)) { renameFunc((Name[0] != 'w') ? "memmove_s" : "wmemmove_s", Result, Diag); @@ -970,15 +972,15 @@ void NotNullTerminatedResultCheck::ncmpFix( if (const CallExpr *StrlenExpr = getStrlenExpr(Result)) { const Expr *LengthExprArg = StrlenExpr->getArg(0); - StringRef FirstExprStr = exprToStr(FirstArgExpr, Result).trim(); - StringRef SecondExprStr = exprToStr(SecondArgExpr, Result).trim(); - StringRef LengthArgStr = exprToStr(LengthExprArg, Result).trim(); + const StringRef FirstExprStr = exprToStr(FirstArgExpr, Result).trim(); + const StringRef SecondExprStr = exprToStr(SecondArgExpr, Result).trim(); + const StringRef LengthArgStr = exprToStr(LengthExprArg, Result).trim(); IsLengthTooLong = LengthArgStr == FirstExprStr || LengthArgStr == SecondExprStr; } else { - int SrcLength = + const int SrcLength = getLength(Result.Nodes.getNodeAs<Expr>(SrcExprName), Result); - int GivenLength = getGivenLength(Result); + const int GivenLength = getGivenLength(Result); if (SrcLength != 0 && GivenLength != 0) IsLengthTooLong = GivenLength > SrcLength; } diff --git a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp index 1b1e0401..19b4fc1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp @@ -101,11 +101,9 @@ void OptionalValueConversionCheck::registerMatchers(MatchFinder *Finder) { hasName(MakeOptional), returns(BindOptionalType)))), hasArgument(0, OptionalDerefMatcher)), - callExpr( - - argumentCountIs(1), + callExpr(argumentCountIs(1), - hasArgument(0, OptionalDerefMatcher))), + hasArgument(0, OptionalDerefMatcher))), unless(anyOf(hasAncestor(typeLoc()), hasAncestor(expr(matchers::hasUnevaluatedContext()))))) .bind("expr"), diff --git a/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp index 57196ad..0084ace 100644 --- a/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/PosixReturnCheck.cpp @@ -66,8 +66,8 @@ void PosixReturnCheck::registerMatchers(MatchFinder *Finder) { void PosixReturnCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *LessThanZeroOp = Result.Nodes.getNodeAs<BinaryOperator>("ltzop")) { - SourceLocation OperatorLoc = LessThanZeroOp->getOperatorLoc(); - StringRef NewBinOp = + const SourceLocation OperatorLoc = LessThanZeroOp->getOperatorLoc(); + const StringRef NewBinOp = LessThanZeroOp->getOpcode() == BinaryOperator::Opcode::BO_LT ? ">" : "<"; diag(OperatorLoc, "the comparison always evaluates to false because %0 " diff --git a/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp index b8bca72..3e32e9b 100644 --- a/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.cpp @@ -6,29 +6,28 @@ // //===----------------------------------------------------------------------===// -#include "ProperlySeededRandomGeneratorCheck.h" +#include "RandomGeneratorSeedCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "llvm/ADT/STLExtras.h" using namespace clang::ast_matchers; -namespace clang::tidy::cert { +namespace clang::tidy::bugprone { -ProperlySeededRandomGeneratorCheck::ProperlySeededRandomGeneratorCheck( - StringRef Name, ClangTidyContext *Context) +RandomGeneratorSeedCheck::RandomGeneratorSeedCheck(StringRef Name, + ClangTidyContext *Context) : ClangTidyCheck(Name, Context), RawDisallowedSeedTypes( Options.get("DisallowedSeedTypes", "time_t,std::time_t")) { RawDisallowedSeedTypes.split(DisallowedSeedTypes, ','); } -void ProperlySeededRandomGeneratorCheck::storeOptions( - ClangTidyOptions::OptionMap &Opts) { +void RandomGeneratorSeedCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "DisallowedSeedTypes", RawDisallowedSeedTypes); } -void ProperlySeededRandomGeneratorCheck::registerMatchers(MatchFinder *Finder) { +void RandomGeneratorSeedCheck::registerMatchers(MatchFinder *Finder) { auto RandomGeneratorEngineDecl = cxxRecordDecl(hasAnyName( "::std::linear_congruential_engine", "::std::mersenne_twister_engine", "::std::subtract_with_carry_engine", "::std::discard_block_engine", @@ -75,8 +74,7 @@ void ProperlySeededRandomGeneratorCheck::registerMatchers(MatchFinder *Finder) { this); } -void ProperlySeededRandomGeneratorCheck::check( - const MatchFinder::MatchResult &Result) { +void RandomGeneratorSeedCheck::check(const MatchFinder::MatchResult &Result) { const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructExpr>("ctor"); if (Ctor) checkSeed(Result, Ctor); @@ -91,8 +89,8 @@ void ProperlySeededRandomGeneratorCheck::check( } template <class T> -void ProperlySeededRandomGeneratorCheck::checkSeed( - const MatchFinder::MatchResult &Result, const T *Func) { +void RandomGeneratorSeedCheck::checkSeed(const MatchFinder::MatchResult &Result, + const T *Func) { if (Func->getNumArgs() == 0 || Func->getArg(0)->isDefaultArgument()) { diag(Func->getExprLoc(), "random number generator seeded with a default argument will generate " @@ -118,4 +116,4 @@ void ProperlySeededRandomGeneratorCheck::checkSeed( } } -} // namespace clang::tidy::cert +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h b/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.h index 8cb2e62..c9c54ea 100644 --- a/clang-tools-extra/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/RandomGeneratorSeedCheck.h @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_PROPERLYSEEDEDRANDOMGENERATORCHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_PROPERLYSEEDEDRANDOMGENERATORCHECK_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_RANDOMGENERATORSEEDCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_RANDOMGENERATORSEEDCHECK_H #include "../ClangTidyCheck.h" #include <string> -namespace clang::tidy::cert { +namespace clang::tidy::bugprone { /// Random number generator must be seeded properly. /// @@ -20,10 +20,10 @@ namespace clang::tidy::cert { /// constant expression is a security vulnerability. /// /// For the user-facing documentation see: -/// https://clang.llvm.org/extra/clang-tidy/checks/cert/msc51-cpp.html -class ProperlySeededRandomGeneratorCheck : public ClangTidyCheck { +/// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/random-generator-seed.html +class RandomGeneratorSeedCheck : public ClangTidyCheck { public: - ProperlySeededRandomGeneratorCheck(StringRef Name, ClangTidyContext *Context); + RandomGeneratorSeedCheck(StringRef Name, ClangTidyContext *Context); void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; @@ -37,6 +37,6 @@ private: SmallVector<StringRef, 5> DisallowedSeedTypes; }; -} // namespace clang::tidy::cert +} // namespace clang::tidy::bugprone -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_PROPERLYSEEDEDRANDOMGENERATORCHECK_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_RANDOMGENERATORSEEDCHECK_H diff --git a/clang-tools-extra/clang-tidy/bugprone/RawMemoryCallOnNonTrivialTypeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/RawMemoryCallOnNonTrivialTypeCheck.cpp index f7f7ccb..e212301 100644 --- a/clang-tools-extra/clang-tidy/bugprone/RawMemoryCallOnNonTrivialTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/RawMemoryCallOnNonTrivialTypeCheck.cpp @@ -64,7 +64,8 @@ void RawMemoryCallOnNonTrivialTypeCheck::storeOptions( void RawMemoryCallOnNonTrivialTypeCheck::registerMatchers(MatchFinder *Finder) { using namespace ast_matchers::internal; - auto IsStructPointer = [](Matcher<CXXRecordDecl> Constraint = anything(), + auto IsStructPointer = [](const Matcher<CXXRecordDecl> &Constraint = + anything(), bool Bind = false) { return expr(unaryOperator( hasOperatorName("&"), @@ -74,8 +75,8 @@ void RawMemoryCallOnNonTrivialTypeCheck::registerMatchers(MatchFinder *Finder) { }; auto IsRecordSizeOf = expr(sizeOfExpr(hasArgumentOfType(equalsBoundNode("Record")))); - auto ArgChecker = [&](Matcher<CXXRecordDecl> RecordConstraint, - BindableMatcher<Stmt> SecondArg = expr()) { + auto ArgChecker = [&](const Matcher<CXXRecordDecl> &RecordConstraint, + const BindableMatcher<Stmt> &SecondArg = expr()) { return allOf(argumentCountIs(3), hasArgument(0, IsStructPointer(RecordConstraint, true)), hasArgument(1, SecondArg), hasArgument(2, IsRecordSizeOf)); diff --git a/clang-tools-extra/clang-tidy/bugprone/RedundantBranchConditionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/RedundantBranchConditionCheck.cpp index 6abe53f..528c254 100644 --- a/clang-tools-extra/clang-tidy/bugprone/RedundantBranchConditionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/RedundantBranchConditionCheck.cpp @@ -112,7 +112,7 @@ void RedundantBranchConditionCheck::check( if (isa<DeclRefExpr>(InnerIf->getCond()->IgnoreParenImpCasts()) || (BinOpCond && BinOpCond->getOpcode() == BO_LOr)) { - SourceLocation IfBegin = InnerIf->getBeginLoc(); + const SourceLocation IfBegin = InnerIf->getBeginLoc(); const Stmt *Body = InnerIf->getThen(); const Expr *OtherSide = nullptr; if (BinOpCond) { @@ -132,9 +132,9 @@ void RedundantBranchConditionCheck::check( // If the other side has side effects then keep it. if (OtherSide && OtherSide->HasSideEffects(*Result.Context)) { - SourceLocation BeforeOtherSide = + const SourceLocation BeforeOtherSide = OtherSide->getBeginLoc().getLocWithOffset(-1); - SourceLocation AfterOtherSide = + const SourceLocation AfterOtherSide = Lexer::findNextToken(OtherSide->getEndLoc(), *Result.SourceManager, getLangOpts()) ->getLocation(); @@ -161,12 +161,12 @@ void RedundantBranchConditionCheck::check( const auto *LeftDRE = dyn_cast<DeclRefExpr>(CondOp->getLHS()->IgnoreParenImpCasts()); if (LeftDRE && LeftDRE->getDecl() == CondVar) { - SourceLocation BeforeRHS = + const SourceLocation BeforeRHS = CondOp->getRHS()->getBeginLoc().getLocWithOffset(-1); Diag << FixItHint::CreateRemoval(CharSourceRange::getTokenRange( CondOp->getLHS()->getBeginLoc(), BeforeRHS)); } else { - SourceLocation AfterLHS = + const SourceLocation AfterLHS = Lexer::findNextToken(CondOp->getLHS()->getEndLoc(), *Result.SourceManager, getLangOpts()) ->getLocation(); diff --git a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp index a3265293..1107cef 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp @@ -83,7 +83,7 @@ static const Decl *findRVRefOverload(const FunctionDecl &FD, // FIXME: // 1. overload in anonymous namespace // 2. forward reference - DeclContext::lookup_result LookupResult = + const DeclContext::lookup_result LookupResult = FD.getParent()->lookup(FD.getNameInfo().getName()); if (LookupResult.isSingleResult()) { return nullptr; diff --git a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp index c262b1c..282a3b2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.cpp @@ -283,7 +283,7 @@ static bool isStandardFunction(const FunctionDecl *FD) { /// This includes all statements that have a class name with "CXX" prefix /// and every other statement that is declared in file ExprCXX.h. static bool isCXXOnlyStmt(const Stmt *S) { - StringRef Name = S->getStmtClassName(); + const StringRef Name = S->getStmtClassName(); if (Name.starts_with("CXX")) return true; // Check for all other class names in ExprCXX.h that have no 'CXX' prefix. @@ -317,7 +317,7 @@ static SourceRange getSourceRangeOfStmt(const Stmt *S, ASTContext &Ctx) { ParentMapContext &PM = Ctx.getParentMapContext(); DynTypedNode P = DynTypedNode::create(*S); while (P.getSourceRange().isInvalid()) { - DynTypedNodeList PL = PM.getParents(P); + const DynTypedNodeList PL = PM.getParents(P); if (PL.size() != 1) return {}; P = PL[0]; @@ -401,14 +401,15 @@ void SignalHandlerCheck::check(const MatchFinder::MatchResult &Result) { } // FIXME: Update CallGraph::getNode to use canonical decl? - CallGraphNode *HandlerNode = CG.getNode(HandlerDecl->getCanonicalDecl()); + const CallGraphNode *HandlerNode = + CG.getNode(HandlerDecl->getCanonicalDecl()); assert(HandlerNode && "Handler with body should be present in the call graph."); // Start from signal handler and visit every function call. auto Itr = llvm::df_begin(HandlerNode), ItrE = llvm::df_end(HandlerNode); while (Itr != ItrE) { const auto *CallF = dyn_cast<FunctionDecl>((*Itr)->getDecl()); - unsigned int PathL = Itr.getPathLength(); + const unsigned int PathL = Itr.getPathLength(); if (CallF) { // A signal handler or a function transitively reachable from the signal // handler was found to be unsafe. @@ -434,8 +435,8 @@ void SignalHandlerCheck::check(const MatchFinder::MatchResult &Result) { bool SignalHandlerCheck::checkFunction( const FunctionDecl *FD, const Expr *CallOrRef, - std::function<void(bool)> ChainReporter) { - bool FunctionIsCalled = isa<CallExpr>(CallOrRef); + llvm::function_ref<void(bool)> ChainReporter) { + const bool FunctionIsCalled = isa<CallExpr>(CallOrRef); if (isStandardFunction(FD)) { if (!isStandardFunctionAsyncSafe(FD)) { @@ -470,7 +471,7 @@ bool SignalHandlerCheck::checkFunction( bool SignalHandlerCheck::checkFunctionCPP14( const FunctionDecl *FD, const Expr *CallOrRef, - std::function<void(bool)> ChainReporter) { + llvm::function_ref<void(bool)> ChainReporter) { if (!FD->isExternC()) { diag(CallOrRef->getBeginLoc(), "functions without C linkage are not allowed as signal " @@ -492,7 +493,7 @@ bool SignalHandlerCheck::checkFunctionCPP14( for (const auto &Match : Matches) { const auto *FoundS = Match.getNodeAs<Stmt>("stmt"); if (isCXXOnlyStmt(FoundS)) { - SourceRange R = getSourceRangeOfStmt(FoundS, Ctx); + const SourceRange R = getSourceRangeOfStmt(FoundS, Ctx); if (R.isInvalid()) continue; diag(R.getBegin(), @@ -531,7 +532,7 @@ bool SignalHandlerCheck::isStandardFunctionAsyncSafe( } void SignalHandlerCheck::reportHandlerChain( - const llvm::df_iterator<clang::CallGraphNode *> &Itr, + const llvm::df_iterator<const clang::CallGraphNode *> &Itr, const DeclRefExpr *HandlerRef, bool SkipPathEnd) { int CallLevel = Itr.getPathLength() - 2; assert(CallLevel >= -1 && "Empty iterator?"); diff --git a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h index b5317793..324b2c8 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/SignalHandlerCheck.h @@ -48,10 +48,10 @@ private: /// The bool parameter is used like \c SkipPathEnd in \c reportHandlerChain . /// \return Returns true if a diagnostic was emitted for this function. bool checkFunction(const FunctionDecl *FD, const Expr *CallOrRef, - std::function<void(bool)> ChainReporter); + llvm::function_ref<void(bool)> ChainReporter); /// Similar as \c checkFunction but only check for C++14 rules. bool checkFunctionCPP14(const FunctionDecl *FD, const Expr *CallOrRef, - std::function<void(bool)> ChainReporter); + llvm::function_ref<void(bool)> ChainReporter); /// Returns true if a standard library function is considered /// asynchronous-safe. bool isStandardFunctionAsyncSafe(const FunctionDecl *FD) const; @@ -65,8 +65,9 @@ private: /// registered as signal handler. /// @param SkipPathEnd If true the last item of the call chain (farthest away /// from the \c signal call) is omitted from note generation. - void reportHandlerChain(const llvm::df_iterator<clang::CallGraphNode *> &Itr, - const DeclRefExpr *HandlerRef, bool SkipPathEnd); + void + reportHandlerChain(const llvm::df_iterator<const clang::CallGraphNode *> &Itr, + const DeclRefExpr *HandlerRef, bool SkipPathEnd); clang::CallGraph CG; diff --git a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp index 742d85b..31c5413 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp @@ -140,7 +140,7 @@ void SignedCharMisuseCheck::check(const MatchFinder::MatchResult &Result) { if (!SignedCastExpression->isValueDependent() && SignedCastExpression->getSubExpr()->EvaluateAsInt(EVResult, *Result.Context)) { - llvm::APSInt Value = EVResult.Val.getInt(); + const llvm::APSInt Value = EVResult.Val.getInt(); if (Value.isNonNegative()) return; } @@ -154,7 +154,7 @@ void SignedCharMisuseCheck::check(const MatchFinder::MatchResult &Result) { if (!UnSignedCastExpression->isValueDependent() && UnSignedCastExpression->getSubExpr()->EvaluateAsInt(EVResult, *Result.Context)) { - llvm::APSInt Value = EVResult.Val.getInt(); + const llvm::APSInt Value = EVResult.Val.getInt(); if (Value <= UnsignedASCIIUpperBound) return; } diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp index 2672dc7..49ba3b8 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp @@ -407,9 +407,9 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) { const auto *ElementTy = Result.Nodes.getNodeAs<Type>("elem-type"); const auto *PointedTy = Result.Nodes.getNodeAs<Type>("elem-ptr-type"); - CharUnits NumeratorSize = getSizeOfType(Ctx, NumTy); - CharUnits DenominatorSize = getSizeOfType(Ctx, DenomTy); - CharUnits ElementSize = getSizeOfType(Ctx, ElementTy); + const CharUnits NumeratorSize = getSizeOfType(Ctx, NumTy); + const CharUnits DenominatorSize = getSizeOfType(Ctx, DenomTy); + const CharUnits ElementSize = getSizeOfType(Ctx, ElementTy); if (DenominatorSize > CharUnits::Zero() && !NumeratorSize.isMultipleOf(DenominatorSize)) { diff --git a/clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.cpp index f76e4a7..af478b1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SmartPtrArrayMismatchCheck.cpp @@ -93,10 +93,10 @@ void SmartPtrArrayMismatchCheck::check(const MatchFinder::MatchResult &Result) { assert(TSTypeLoc.getNumArgs() >= 1 && "Matched type should have at least 1 template argument."); - SourceRange TemplateArgumentRange = TSTypeLoc.getArgLoc(0) - .getTypeSourceInfo() - ->getTypeLoc() - .getSourceRange(); + const SourceRange TemplateArgumentRange = TSTypeLoc.getArgLoc(0) + .getTypeSourceInfo() + ->getTypeLoc() + .getSourceRange(); D << TemplateArgumentRange; if (isInSingleDeclStmt(VarOrField)) { @@ -104,7 +104,7 @@ void SmartPtrArrayMismatchCheck::check(const MatchFinder::MatchResult &Result) { if (!utils::rangeCanBeFixed(TemplateArgumentRange, &SM)) return; - SourceLocation InsertLoc = Lexer::getLocForEndOfToken( + const SourceLocation InsertLoc = Lexer::getLocForEndOfToken( TemplateArgumentRange.getEnd(), 0, SM, Ctx.getLangOpts()); D << FixItHint::CreateInsertion(InsertLoc, "[]"); } diff --git a/clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp index 1e8058b..fd82b1c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SpuriouslyWakeUpFunctionsCheck.cpp @@ -15,7 +15,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { void SpuriouslyWakeUpFunctionsCheck::registerMatchers(MatchFinder *Finder) { - auto HasUniqueLock = hasDescendant(declRefExpr( hasDeclaration(varDecl(hasType(recordDecl(classTemplateSpecializationDecl( hasName("::std::unique_lock"), @@ -45,9 +44,7 @@ void SpuriouslyWakeUpFunctionsCheck::registerMatchers(MatchFinder *Finder) { onImplicitObjectArgument( declRefExpr(to(varDecl(hasType(references(recordDecl( hasName("::std::condition_variable")))))))), - HasUniqueLock) - - )) + HasUniqueLock))) .bind("wait")); auto HasWaitDescendantC = hasDescendant( @@ -77,7 +74,7 @@ void SpuriouslyWakeUpFunctionsCheck::registerMatchers(MatchFinder *Finder) { void SpuriouslyWakeUpFunctionsCheck::check( const MatchFinder::MatchResult &Result) { const auto *MatchedWait = Result.Nodes.getNodeAs<CallExpr>("wait"); - StringRef WaitName = MatchedWait->getDirectCallee()->getName(); + const StringRef WaitName = MatchedWait->getDirectCallee()->getName(); diag(MatchedWait->getExprLoc(), "'%0' should be placed inside a while statement %select{|or used with a " "conditional parameter}1") diff --git a/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp index a7958cc..056ae4b8 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StandaloneEmptyCheck.cpp @@ -117,12 +117,13 @@ void StandaloneEmptyCheck::check(const MatchFinder::MatchResult &Result) { if (ParentReturnStmt) return; - SourceLocation MemberLoc = MemberCall->getBeginLoc(); - SourceLocation ReplacementLoc = MemberCall->getExprLoc(); - SourceRange ReplacementRange = SourceRange(ReplacementLoc, ReplacementLoc); + const SourceLocation MemberLoc = MemberCall->getBeginLoc(); + const SourceLocation ReplacementLoc = MemberCall->getExprLoc(); + const SourceRange ReplacementRange = + SourceRange(ReplacementLoc, ReplacementLoc); ASTContext &Context = MemberCall->getRecordDecl()->getASTContext(); - DeclarationName Name = + const DeclarationName Name = Context.DeclarationNames.getIdentifier(&Context.Idents.get("clear")); auto Candidates = HeuristicResolver(Context).lookupDependentName( @@ -133,11 +134,12 @@ void StandaloneEmptyCheck::check(const MatchFinder::MatchResult &Result) { !llvm::cast<CXXMethodDecl>(ND)->isConst(); }); - bool HasClear = !Candidates.empty(); + const bool HasClear = !Candidates.empty(); if (HasClear) { const auto *Clear = llvm::cast<CXXMethodDecl>(Candidates.at(0)); - QualType RangeType = MemberCall->getImplicitObjectArgument()->getType(); - bool QualifierIncompatible = + const QualType RangeType = + MemberCall->getImplicitObjectArgument()->getType(); + const bool QualifierIncompatible = (!Clear->isVolatile() && RangeType.isVolatileQualified()) || RangeType.isConstQualified(); if (!QualifierIncompatible) { @@ -162,8 +164,8 @@ void StandaloneEmptyCheck::check(const MatchFinder::MatchResult &Result) { if (NonMemberCall->getNumArgs() != 1) return; - SourceLocation NonMemberLoc = NonMemberCall->getExprLoc(); - SourceLocation NonMemberEndLoc = NonMemberCall->getEndLoc(); + const SourceLocation NonMemberLoc = NonMemberCall->getExprLoc(); + const SourceLocation NonMemberEndLoc = NonMemberCall->getEndLoc(); const Expr *Arg = NonMemberCall->getArg(0); CXXRecordDecl *ArgRecordDecl = Arg->getType()->getAsCXXRecordDecl(); @@ -171,7 +173,7 @@ void StandaloneEmptyCheck::check(const MatchFinder::MatchResult &Result) { return; ASTContext &Context = ArgRecordDecl->getASTContext(); - DeclarationName Name = + const DeclarationName Name = Context.DeclarationNames.getIdentifier(&Context.Idents.get("clear")); auto Candidates = HeuristicResolver(Context).lookupDependentName( @@ -182,20 +184,20 @@ void StandaloneEmptyCheck::check(const MatchFinder::MatchResult &Result) { !llvm::cast<CXXMethodDecl>(ND)->isConst(); }); - bool HasClear = !Candidates.empty(); + const bool HasClear = !Candidates.empty(); if (HasClear) { const auto *Clear = llvm::cast<CXXMethodDecl>(Candidates.at(0)); - bool QualifierIncompatible = + const bool QualifierIncompatible = (!Clear->isVolatile() && Arg->getType().isVolatileQualified()) || Arg->getType().isConstQualified(); if (!QualifierIncompatible) { - std::string ReplacementText = + const std::string ReplacementText = std::string(Lexer::getSourceText( CharSourceRange::getTokenRange(Arg->getSourceRange()), *Result.SourceManager, getLangOpts())) + ".clear()"; - SourceRange ReplacementRange = + const SourceRange ReplacementRange = SourceRange(NonMemberLoc, NonMemberEndLoc); diag(NonMemberLoc, "ignoring the result of '%0'; did you mean 'clear()'?") diff --git a/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp index 13e5c03..1dff741 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StdNamespaceModificationCheck.cpp @@ -20,12 +20,12 @@ AST_POLYMORPHIC_MATCHER_P( AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl, TemplateSpecializationType, FunctionDecl), clang::ast_matchers::internal::Matcher<TemplateArgument>, InnerMatcher) { - ArrayRef<TemplateArgument> Args = + const ArrayRef<TemplateArgument> Args = clang::ast_matchers::internal::getTemplateSpecializationArgs(Node); for (const auto &Arg : Args) { if (Arg.getKind() != TemplateArgument::Pack) continue; - ArrayRef<TemplateArgument> PackArgs = Arg.getPackAsArray(); + const ArrayRef<TemplateArgument> PackArgs = Arg.getPackAsArray(); if (matchesFirstInRange(InnerMatcher, PackArgs.begin(), PackArgs.end(), Finder, Builder) != PackArgs.end()) return true; diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 832377e..d2e631e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -29,8 +29,8 @@ static std::vector<StringRef> removeNamespaces(const std::vector<StringRef> &Names) { std::vector<StringRef> Result; Result.reserve(Names.size()); - for (StringRef Name : Names) { - std::string::size_type ColonPos = Name.rfind(':'); + for (const StringRef Name : Names) { + const std::string::size_type ColonPos = Name.rfind(':'); Result.push_back( Name.substr(ColonPos == std::string::npos ? 0 : ColonPos + 1)); } @@ -168,7 +168,7 @@ void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { const ASTContext &Ctx = *Result.Context; const auto *E = Result.Nodes.getNodeAs<CXXConstructExpr>("constructor"); assert(E && "missing constructor expression"); - SourceLocation Loc = E->getBeginLoc(); + const SourceLocation Loc = E->getBeginLoc(); if (Result.Nodes.getNodeAs<Expr>("swapped-parameter")) { const Expr *P0 = E->getArg(0); diff --git a/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp index 93a55ef54..8454fd1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp @@ -129,7 +129,7 @@ void StringIntegerAssignmentCheck::check( const auto *Argument = Result.Nodes.getNodeAs<Expr>("expr"); const auto CharType = Result.Nodes.getNodeAs<QualType>("type")->getCanonicalType(); - SourceLocation Loc = Argument->getBeginLoc(); + const SourceLocation Loc = Argument->getBeginLoc(); // Try to detect a few common expressions to reduce false positives. if (CharExpressionDetector(CharType, *Result.Context) @@ -145,7 +145,7 @@ void StringIntegerAssignmentCheck::check( if (Loc.isMacroID()) return; - bool IsWideCharType = CharType->isWideCharType(); + const bool IsWideCharType = CharType->isWideCharType(); if (!CharType->isCharType() && !IsWideCharType) return; bool IsOneDigit = false; @@ -155,7 +155,7 @@ void StringIntegerAssignmentCheck::check( IsLiteral = true; } - SourceLocation EndLoc = Lexer::getLocForEndOfToken( + const SourceLocation EndLoc = Lexer::getLocForEndOfToken( Argument->getEndLoc(), 0, *Result.SourceManager, getLangOpts()); if (IsOneDigit) { Diag << FixItHint::CreateInsertion(Loc, IsWideCharType ? "L'" : "'") diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp index 8dbe1c0..ef7f0b5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp @@ -54,7 +54,7 @@ static int enumLength(const EnumDecl *EnumDec) { static bool hasDisjointValueRange(const EnumDecl *Enum1, const EnumDecl *Enum2) { - ValueRange Range1(Enum1), Range2(Enum2); + const ValueRange Range1(Enum1), Range2(Enum2); return llvm::APSInt::compareValues(Range1.MaxVal, Range2.MinVal) < 0 || llvm::APSInt::compareValues(Range2.MaxVal, Range1.MinVal) < 0; } @@ -94,9 +94,9 @@ static int countNonPowOfTwoLiteralNum(const EnumDecl *EnumDec) { /// last enumerator is the sum of the lesser values (and initialized by a /// literal) or when it could contain consecutive values. static bool isPossiblyBitMask(const EnumDecl *EnumDec) { - ValueRange VR(EnumDec); - int EnumLen = enumLength(EnumDec); - int NonPowOfTwoCounter = countNonPowOfTwoLiteralNum(EnumDec); + const ValueRange VR(EnumDec); + const int EnumLen = enumLength(EnumDec); + const int NonPowOfTwoCounter = countNonPowOfTwoLiteralNum(EnumDec); return NonPowOfTwoCounter >= 1 && NonPowOfTwoCounter <= 2 && NonPowOfTwoCounter < EnumLen / 2 && (VR.MaxVal - VR.MinVal != EnumLen - 1) && diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp index aaf0594..5abbada 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousIncludeCheck.cpp @@ -66,7 +66,7 @@ void SuspiciousIncludePPCallbacks::InclusionDirective( if (!Check.IgnoredRegexString.empty() && Check.IgnoredRegex.match(FileName)) return; - SourceLocation DiagLoc = FilenameRange.getBegin().getLocWithOffset(1); + const SourceLocation DiagLoc = FilenameRange.getBegin().getLocWithOffset(1); const std::optional<StringRef> IFE = utils::getFileExtension(FileName, Check.ImplementationFileExtensions); @@ -81,7 +81,7 @@ void SuspiciousIncludePPCallbacks::InclusionDirective( llvm::sys::path::replace_extension(GuessedFileName, (!HFE.empty() ? "." : "") + HFE); - OptionalFileEntryRef File = + const OptionalFileEntryRef File = PP->LookupFile(DiagLoc, GuessedFileName, IsAngled, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (File) { diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp index d1df2a8..7890afb 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemoryComparisonCheck.cpp @@ -44,10 +44,10 @@ void SuspiciousMemoryComparisonCheck::check( for (unsigned int ArgIndex = 0; ArgIndex < 2; ++ArgIndex) { const Expr *ArgExpr = CE->getArg(ArgIndex); - QualType ArgType = ArgExpr->IgnoreImplicit()->getType(); + const QualType ArgType = ArgExpr->IgnoreImplicit()->getType(); const Type *PointeeType = ArgType->getPointeeOrArrayElementType(); assert(PointeeType != nullptr && "PointeeType should always be available."); - QualType PointeeQualifiedType(PointeeType, 0); + const QualType PointeeQualifiedType(PointeeType, 0); if (PointeeType->isRecordType()) { if (const RecordDecl *RD = @@ -65,7 +65,7 @@ void SuspiciousMemoryComparisonCheck::check( } if (!PointeeType->isIncompleteType()) { - uint64_t PointeeSize = Ctx.getTypeSize(PointeeType); + const uint64_t PointeeSize = Ctx.getTypeSize(PointeeType); if (ComparedBits && *ComparedBits >= PointeeSize && !Ctx.hasUniqueObjectRepresentations(PointeeQualifiedType)) { diag(CE->getBeginLoc(), diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp index b1d12ba..63ba2ed 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp @@ -60,7 +60,7 @@ void SuspiciousMemsetUsageCheck::check(const MatchFinder::MatchResult &Result) { // Case 1: fill_char of memset() is a character '0'. Probably an // integer zero was intended. - SourceRange CharRange = CharZeroFill->getSourceRange(); + const SourceRange CharRange = CharZeroFill->getSourceRange(); auto Diag = diag(CharZeroFill->getBeginLoc(), "memset fill value is char '0', " "potentially mistaken for int 0"); @@ -70,10 +70,8 @@ void SuspiciousMemsetUsageCheck::check(const MatchFinder::MatchResult &Result) { return; Diag << FixItHint::CreateReplacement( CharSourceRange::getTokenRange(CharRange), "0"); - } - - else if (const auto *NumFill = - Result.Nodes.getNodeAs<IntegerLiteral>("num-fill")) { + } else if (const auto *NumFill = + Result.Nodes.getNodeAs<IntegerLiteral>("num-fill")) { // Case 2: fill_char of memset() is larger in size than an unsigned char // so it gets truncated during conversion. @@ -82,15 +80,13 @@ void SuspiciousMemsetUsageCheck::check(const MatchFinder::MatchResult &Result) { if (!NumFill->EvaluateAsInt(EVResult, *Result.Context)) return; - llvm::APSInt NumValue = EVResult.Val.getInt(); + const llvm::APSInt NumValue = EVResult.Val.getInt(); if (NumValue >= 0 && NumValue <= UCharMax) return; diag(NumFill->getBeginLoc(), "memset fill value is out of unsigned " "character range, gets truncated"); - } - - else if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call")) { + } else if (const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call")) { // Case 3: byte_count of memset() is zero. This is most likely an // argument swap. @@ -110,7 +106,7 @@ void SuspiciousMemsetUsageCheck::check(const MatchFinder::MatchResult &Result) { Expr::EvalResult EVResult; if (!FillChar->isValueDependent() && FillChar->EvaluateAsInt(EVResult, *Result.Context)) { - llvm::APSInt Value1 = EVResult.Val.getInt(); + const llvm::APSInt Value1 = EVResult.Val.getInt(); if (Value1 == 0 || Value1.isNegative()) return; } @@ -120,8 +116,10 @@ void SuspiciousMemsetUsageCheck::check(const MatchFinder::MatchResult &Result) { // and fix-its to swap the arguments. auto D = diag(Call->getBeginLoc(), "memset of size zero, potentially swapped arguments"); - StringRef RHSString = tooling::fixit::getText(*ByteCount, *Result.Context); - StringRef LHSString = tooling::fixit::getText(*FillChar, *Result.Context); + const StringRef RHSString = + tooling::fixit::getText(*ByteCount, *Result.Context); + const StringRef LHSString = + tooling::fixit::getText(*FillChar, *Result.Context); if (LHSString.empty() || RHSString.empty()) return; diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp index a41f650..4f0d819 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp @@ -19,7 +19,7 @@ static bool isConcatenatedLiteralsOnPurpose(ASTContext *Ctx, // String literals surrounded by parentheses are assumed to be on purpose. // i.e.: const char* Array[] = { ("a" "b" "c"), "d", [...] }; - TraversalKindScope RAII(*Ctx, TK_AsIs); + const TraversalKindScope RAII(*Ctx, TK_AsIs); auto Parents = Ctx->getParents(*Lit); if (Parents.size() == 1 && Parents[0].get<ParenExpr>() != nullptr) return true; @@ -35,15 +35,15 @@ static bool isConcatenatedLiteralsOnPurpose(ASTContext *Ctx, // }; const SourceManager &SM = Ctx->getSourceManager(); bool IndentedCorrectly = true; - SourceLocation FirstToken = Lit->getStrTokenLoc(0); - FileID BaseFID = SM.getFileID(FirstToken); - unsigned int BaseIndent = SM.getSpellingColumnNumber(FirstToken); - unsigned int BaseLine = SM.getSpellingLineNumber(FirstToken); + const SourceLocation FirstToken = Lit->getStrTokenLoc(0); + const FileID BaseFID = SM.getFileID(FirstToken); + const unsigned int BaseIndent = SM.getSpellingColumnNumber(FirstToken); + const unsigned int BaseLine = SM.getSpellingLineNumber(FirstToken); for (unsigned int TokNum = 1; TokNum < Lit->getNumConcatenated(); ++TokNum) { - SourceLocation Token = Lit->getStrTokenLoc(TokNum); - FileID FID = SM.getFileID(Token); - unsigned int Indent = SM.getSpellingColumnNumber(Token); - unsigned int Line = SM.getSpellingLineNumber(Token); + const SourceLocation Token = Lit->getStrTokenLoc(TokNum); + const FileID FID = SM.getFileID(Token); + const unsigned int Indent = SM.getSpellingColumnNumber(Token); + const unsigned int Line = SM.getSpellingLineNumber(Token); if (FID != BaseFID || Line != BaseLine + TokNum || Indent <= BaseIndent) { IndentedCorrectly = false; break; @@ -100,7 +100,7 @@ void SuspiciousMissingCommaCheck::check( assert(InitializerList && ConcatenatedLiteral); // Skip small arrays as they often generate false-positive. - unsigned int Size = InitializerList->getNumInits(); + const unsigned int Size = InitializerList->getNumInits(); if (Size < SizeThreshold) return; @@ -116,7 +116,7 @@ void SuspiciousMissingCommaCheck::check( // Warn only when concatenation is not common in this initializer list. // The current threshold is set to less than 1/5 of the string literals. - if (double(Count) / Size > RatioThreshold) + if (static_cast<double>(Count) / Size > RatioThreshold) return; diag(ConcatenatedLiteral->getBeginLoc(), diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousReallocUsageCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousReallocUsageCheck.cpp index b5da801..bf31218 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousReallocUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousReallocUsageCheck.cpp @@ -44,7 +44,7 @@ public: return false; if (!check(E1->getBase(), E2->getBase())) return false; - DeclAccessPair FD = E1->getFoundDecl(); + const DeclAccessPair FD = E1->getFoundDecl(); return isa<FieldDecl>(FD.getDecl()) && FD == E2->getFoundDecl(); } @@ -92,10 +92,9 @@ public: return false; } bool VisitStmt(const Stmt *S) { - for (const Stmt *Child : S->children()) - if (Child && Visit(Child)) - return true; - return false; + return llvm::any_of(S->children(), [this](const Stmt *Child) { + return Child && Visit(Child); + }); } }; @@ -145,7 +144,7 @@ void SuspiciousReallocUsageCheck::check( if (FindAssignToVarBefore{Var, DeclRef, SM}.Visit(Func->getBody())) return; - StringRef CodeOfAssignedExpr = Lexer::getSourceText( + const StringRef CodeOfAssignedExpr = Lexer::getSourceText( CharSourceRange::getTokenRange(PtrResultExpr->getSourceRange()), SM, getLangOpts()); diag(Call->getBeginLoc(), "'%0' may be set to null if 'realloc' fails, which " diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp index 543d312..9d37fc1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp @@ -31,7 +31,7 @@ void SuspiciousSemicolonCheck::check(const MatchFinder::MatchResult &Result) { return; const auto *Semicolon = Result.Nodes.getNodeAs<NullStmt>("semi"); - SourceLocation LocStart = Semicolon->getBeginLoc(); + const SourceLocation LocStart = Semicolon->getBeginLoc(); if (LocStart.isMacroID()) return; @@ -40,7 +40,7 @@ void SuspiciousSemicolonCheck::check(const MatchFinder::MatchResult &Result) { auto Token = utils::lexer::getPreviousToken(LocStart, Ctxt.getSourceManager(), Ctxt.getLangOpts()); auto &SM = *Result.SourceManager; - unsigned SemicolonLine = SM.getSpellingLineNumber(LocStart); + const unsigned SemicolonLine = SM.getSpellingLineNumber(LocStart); const auto *Statement = Result.Nodes.getNodeAs<Stmt>("stmt"); const bool IsIfStmt = isa<IfStmt>(Statement); @@ -49,18 +49,20 @@ void SuspiciousSemicolonCheck::check(const MatchFinder::MatchResult &Result) { SM.getSpellingLineNumber(Token.getLocation()) != SemicolonLine) return; - SourceLocation LocEnd = Semicolon->getEndLoc(); - FileID FID = SM.getFileID(LocEnd); - llvm::MemoryBufferRef Buffer = SM.getBufferOrFake(FID, LocEnd); + const SourceLocation LocEnd = Semicolon->getEndLoc(); + const FileID FID = SM.getFileID(LocEnd); + const llvm::MemoryBufferRef Buffer = SM.getBufferOrFake(FID, LocEnd); Lexer Lexer(SM.getLocForStartOfFile(FID), Ctxt.getLangOpts(), Buffer.getBufferStart(), SM.getCharacterData(LocEnd) + 1, Buffer.getBufferEnd()); if (Lexer.LexFromRawLexer(Token)) return; - unsigned BaseIndent = SM.getSpellingColumnNumber(Statement->getBeginLoc()); - unsigned NewTokenIndent = SM.getSpellingColumnNumber(Token.getLocation()); - unsigned NewTokenLine = SM.getSpellingLineNumber(Token.getLocation()); + const unsigned BaseIndent = + SM.getSpellingColumnNumber(Statement->getBeginLoc()); + const unsigned NewTokenIndent = + SM.getSpellingColumnNumber(Token.getLocation()); + const unsigned NewTokenLine = SM.getSpellingLineNumber(Token.getLocation()); if (!IsIfStmt && NewTokenIndent <= BaseIndent && Token.getKind() != tok::l_brace && NewTokenLine != SemicolonLine) diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp index 7519685..5da9240 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp @@ -88,7 +88,7 @@ void SuspiciousStringCompareCheck::registerMatchers(MatchFinder *Finder) { // Add the list of known string compare-like functions and add user-defined // functions. - std::vector<StringRef> FunctionNames = utils::options::parseListPair( + const std::vector<StringRef> FunctionNames = utils::options::parseListPair( KnownStringCompareFunctions, StringCompareLikeFunctions); // Match a call to a string compare functions. @@ -163,7 +163,7 @@ void SuspiciousStringCompareCheck::check( assert(Decl != nullptr && Call != nullptr); if (Result.Nodes.getNodeAs<Stmt>("missing-comparison")) { - SourceLocation EndLoc = Lexer::getLocForEndOfToken( + const SourceLocation EndLoc = Lexer::getLocForEndOfToken( Call->getRParenLoc(), 0, Result.Context->getSourceManager(), getLangOpts()); @@ -173,10 +173,10 @@ void SuspiciousStringCompareCheck::check( } if (const auto *E = Result.Nodes.getNodeAs<Expr>("logical-not-comparison")) { - SourceLocation EndLoc = Lexer::getLocForEndOfToken( + const SourceLocation EndLoc = Lexer::getLocForEndOfToken( Call->getRParenLoc(), 0, Result.Context->getSourceManager(), getLangOpts()); - SourceLocation NotLoc = E->getBeginLoc(); + const SourceLocation NotLoc = E->getBeginLoc(); diag(Call->getBeginLoc(), "function %0 is compared using logical not operator") diff --git a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.cpp index d239cbe..cb37976 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SuspiciousStringviewDataUsageCheck.cpp @@ -43,7 +43,6 @@ SuspiciousStringviewDataUsageCheck::getCheckTraversalKind() const { } void SuspiciousStringviewDataUsageCheck::registerMatchers(MatchFinder *Finder) { - auto AncestorCall = anyOf( cxxConstructExpr(), callExpr(unless(cxxOperatorCallExpr())), lambdaExpr(), initListExpr( diff --git a/clang-tools-extra/clang-tidy/bugprone/SwappedArgumentsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SwappedArgumentsCheck.cpp index bcedff5..152c0cb 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SwappedArgumentsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SwappedArgumentsCheck.cpp @@ -70,7 +70,7 @@ static bool areArgumentsPotentiallySwapped(const QualType LTo, if (LTo == RFrom && REq) return true; - bool LEq = areTypesSemiEqual(LTo, RFrom); + const bool LEq = areTypesSemiEqual(LTo, RFrom); if (RTo == LFrom && LEq) return true; diff --git a/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp index a85a136..c0d38dc 100644 --- a/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp @@ -104,7 +104,6 @@ void TaggedUnionMemberCountCheck::storeOptions( } void TaggedUnionMemberCountCheck::registerMatchers(MatchFinder *Finder) { - auto NotFromSystemHeaderOrStdNamespace = unless(anyOf(isExpansionInSystemHeader(), isInStdNamespace())); diff --git a/clang-tools-extra/clang-tidy/bugprone/ThrowingStaticInitializationCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ThrowingStaticInitializationCheck.cpp index 56ec5a5..80905e2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ThrowingStaticInitializationCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ThrowingStaticInitializationCheck.cpp @@ -44,7 +44,7 @@ void ThrowingStaticInitializationCheck::check( "duration may throw an exception that cannot be caught") << VD << (VD->getStorageDuration() == SD_Static ? 0 : 1); - SourceLocation FuncLocation = Func->getLocation(); + const SourceLocation FuncLocation = Func->getLocation(); if (FuncLocation.isValid()) { diag(FuncLocation, "possibly throwing %select{constructor|function}0 declared here", diff --git a/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp index 536b680..71b785f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp @@ -67,21 +67,21 @@ void TooSmallLoopVariableCheck::storeOptions( /// LoopName: The entire for loop (as a ForStmt) /// void TooSmallLoopVariableCheck::registerMatchers(MatchFinder *Finder) { - StatementMatcher LoopVarMatcher = + const StatementMatcher LoopVarMatcher = expr(ignoringParenImpCasts( anyOf(declRefExpr(to(varDecl(hasType(isInteger())))), memberExpr(member(fieldDecl(hasType(isInteger()))))))) .bind(LoopVarName); // We need to catch only those comparisons which contain any integer cast. - StatementMatcher LoopVarConversionMatcher = traverse( + const StatementMatcher LoopVarConversionMatcher = traverse( TK_AsIs, implicitCastExpr(hasImplicitDestinationType(isInteger()), has(ignoringParenImpCasts(LoopVarMatcher))) .bind(LoopVarCastName)); // We are interested in only those cases when the loop bound is a variable // value (not const, enum, etc.). - StatementMatcher LoopBoundMatcher = + const StatementMatcher LoopBoundMatcher = expr(ignoringParenImpCasts(allOf( hasType(isInteger()), unless(integerLiteral()), unless(allOf( @@ -94,7 +94,7 @@ void TooSmallLoopVariableCheck::registerMatchers(MatchFinder *Finder) { // We use the loop increment expression only to make sure we found the right // loop variable. - StatementMatcher IncrementMatcher = + const StatementMatcher IncrementMatcher = expr(ignoringParenImpCasts(hasType(isInteger()))).bind(LoopIncrementName); Finder->addMatcher( @@ -121,14 +121,14 @@ static MagnitudeBits calcMagnitudeBits(const ASTContext &Context, const Expr *IntExpr) { assert(IntExprType->isIntegerType()); - unsigned SignedBits = IntExprType->isUnsignedIntegerType() ? 0U : 1U; + const unsigned SignedBits = IntExprType->isUnsignedIntegerType() ? 0U : 1U; if (const auto *BitField = IntExpr->getSourceBitField()) { - unsigned BitFieldWidth = BitField->getBitWidthValue(); + const unsigned BitFieldWidth = BitField->getBitWidthValue(); return {BitFieldWidth - SignedBits, BitFieldWidth}; } - unsigned IntWidth = Context.getIntWidth(IntExprType); + const unsigned IntWidth = Context.getIntWidth(IntExprType); return {IntWidth - SignedBits, 0U}; } @@ -143,18 +143,18 @@ calcUpperBoundMagnitudeBits(const ASTContext &Context, const Expr *UpperBound, const Expr *RHSE = BinOperator->getRHS()->IgnoreParenImpCasts(); const Expr *LHSE = BinOperator->getLHS()->IgnoreParenImpCasts(); - QualType RHSEType = RHSE->getType(); - QualType LHSEType = LHSE->getType(); + const QualType RHSEType = RHSE->getType(); + const QualType LHSEType = LHSE->getType(); if (!RHSEType->isIntegerType() || !LHSEType->isIntegerType()) return {}; - bool RHSEIsConstantValue = RHSEType->isEnumeralType() || - RHSEType.isConstQualified() || - isa<IntegerLiteral>(RHSE); - bool LHSEIsConstantValue = LHSEType->isEnumeralType() || - LHSEType.isConstQualified() || - isa<IntegerLiteral>(LHSE); + const bool RHSEIsConstantValue = RHSEType->isEnumeralType() || + RHSEType.isConstQualified() || + isa<IntegerLiteral>(RHSE); + const bool LHSEIsConstantValue = LHSEType->isEnumeralType() || + LHSEType.isConstQualified() || + isa<IntegerLiteral>(LHSE); // Avoid false positives produced by two constant values. if (RHSEIsConstantValue && LHSEIsConstantValue) @@ -193,7 +193,7 @@ void TooSmallLoopVariableCheck::check(const MatchFinder::MatchResult &Result) { if (LoopVar->getType() != LoopIncrement->getType()) return; - ASTContext &Context = *Result.Context; + const ASTContext &Context = *Result.Context; const QualType LoopVarType = LoopVar->getType(); const MagnitudeBits LoopVarMagnitudeBits = diff --git a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h index 11086fb..62bf42d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h @@ -25,7 +25,8 @@ class UncheckedOptionalAccessCheck : public ClangTidyCheck { public: UncheckedOptionalAccessCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - ModelOptions{Options.get("IgnoreSmartPointerDereference", false)} {} + ModelOptions{Options.get("IgnoreSmartPointerDereference", false), + Options.get("IgnoreValueCalls", false)} {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { @@ -34,6 +35,7 @@ public: void storeOptions(ClangTidyOptions::OptionMap &Opts) override { Options.store(Opts, "IgnoreSmartPointerDereference", ModelOptions.IgnoreSmartPointerDereference); + Options.store(Opts, "IgnoreValueCalls", ModelOptions.IgnoreValueCalls); } private: diff --git a/clang-tools-extra/clang-tidy/bugprone/UncheckedStringToNumberConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UncheckedStringToNumberConversionCheck.cpp index d0bf72b..b82c9d3 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UncheckedStringToNumberConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedStringToNumberConversionCheck.cpp @@ -76,7 +76,8 @@ static ConversionKind classifyFormatString(StringRef Fmt, const LangOptions &LO, // Get the conversion specifier and use it to determine the conversion // kind. - analyze_scanf::ScanfConversionSpecifier SCS = FS.getConversionSpecifier(); + const analyze_scanf::ScanfConversionSpecifier SCS = + FS.getConversionSpecifier(); if (SCS.isIntArg()) { switch (FS.getLengthModifier().getKind()) { case analyze_scanf::LengthModifier::AsLongLong: @@ -194,7 +195,7 @@ void UncheckedStringToNumberConversionCheck::check( // The format string comes from the call expression and depends on which // flavor of scanf is called. // Index 0: scanf, vscanf, Index 1: fscanf, sscanf, vfscanf, vsscanf. - unsigned Idx = + const unsigned Idx = (FFD->getName() == "scanf" || FFD->getName() == "vscanf") ? 0 : 1; // Given the index, see if the call expression argument at that index is diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp index bf30753..340b136 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp @@ -16,7 +16,8 @@ namespace { AST_MATCHER_P(CXXTryStmt, hasHandlerFor, ast_matchers::internal::Matcher<QualType>, InnerMatcher) { - for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) { + const unsigned NH = Node.getNumHandlers(); + for (unsigned I = 0; I < NH; ++I) { const CXXCatchStmt *CatchS = Node.getHandler(I); // Check for generic catch handler (match anything). if (CatchS->getCaughtType().isNull()) @@ -31,7 +32,7 @@ AST_MATCHER_P(CXXTryStmt, hasHandlerFor, } AST_MATCHER(CXXNewExpr, mayThrow) { - FunctionDecl *OperatorNew = Node.getOperatorNew(); + const FunctionDecl *OperatorNew = Node.getOperatorNew(); if (!OperatorNew) return false; return !OperatorNew->getType()->castAs<FunctionProtoType>()->isNothrow(); diff --git a/clang-tools-extra/clang-tidy/bugprone/UnintendedCharOstreamOutputCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnintendedCharOstreamOutputCheck.cpp index bce4657..e10b17c 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnintendedCharOstreamOutputCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnintendedCharOstreamOutputCheck.cpp @@ -80,17 +80,17 @@ void UnintendedCharOstreamOutputCheck::check( const Expr *Value = Call->getArg(1); const SourceRange SourceRange = Value->getSourceRange(); - DiagnosticBuilder Builder = + const DiagnosticBuilder Builder = diag(Call->getOperatorLoc(), "%0 passed to 'operator<<' outputs as character instead of integer. " "cast to 'unsigned int' to print numeric value or cast to 'char' to " "print as character") << Value->getType() << SourceRange; - QualType T = Value->getType(); + const QualType T = Value->getType(); const Type *UnqualifiedDesugaredType = T->getUnqualifiedDesugaredType(); - llvm::StringRef CastType = CastTypeName.value_or( + const llvm::StringRef CastType = CastTypeName.value_or( UnqualifiedDesugaredType->isSpecificBuiltinType(BuiltinType::SChar) ? "int" : "unsigned int"); diff --git a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp index 61ccd26..0a7467a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnsafeFunctionsCheck.cpp @@ -141,7 +141,7 @@ parseCheckedFunctions(StringRef Option, ClangTidyContext *Context) { std::vector<UnsafeFunctionsCheck::CheckedFunction> Result; Result.reserve(Functions.size()); - for (StringRef Function : Functions) { + for (const StringRef Function : Functions) { if (Function.empty()) continue; @@ -266,8 +266,8 @@ void UnsafeFunctionsCheck::registerMatchers(MatchFinder *Finder) { } void UnsafeFunctionsCheck::check(const MatchFinder::MatchResult &Result) { - const Expr *SourceExpr; - const FunctionDecl *FuncDecl; + const Expr *SourceExpr = nullptr; + const FunctionDecl *FuncDecl = nullptr; if (const auto *DeclRef = Result.Nodes.getNodeAs<DeclRefExpr>(DeclRefId)) { SourceExpr = DeclRef; @@ -304,11 +304,17 @@ void UnsafeFunctionsCheck::check(const MatchFinder::MatchResult &Result) { StringRef Reason = Entry.Reason.empty() ? "is marked as unsafe" : Entry.Reason.c_str(); - if (Entry.Replacement.empty()) { + // Omit the replacement, when a fully-custom reason is given. + if (Reason.consume_front(">")) { + diag(SourceExpr->getExprLoc(), "function %0 %1") + << FuncDecl << Reason.trim() << SourceExpr->getSourceRange(); + // Do not recommend a replacement when it is not present. + } else if (Entry.Replacement.empty()) { diag(SourceExpr->getExprLoc(), "function %0 %1; it should not be used") << FuncDecl << Reason << Entry.Replacement << SourceExpr->getSourceRange(); + // Otherwise, emit the replacement. } else { diag(SourceExpr->getExprLoc(), "function %0 %1; '%2' should be used instead") diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp index dae679b..6502fc9 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp @@ -37,8 +37,8 @@ void UnusedRaiiCheck::registerMatchers(MatchFinder *Finder) { } template <typename T> -static void reportDiagnostic(DiagnosticBuilder D, const T *Node, SourceRange SR, - bool DefaultConstruction) { +static void reportDiagnostic(const DiagnosticBuilder &D, const T *Node, + SourceRange SR, bool DefaultConstruction) { const char *Replacement = " give_me_a_name"; // If this is a default ctor we have to remove the parens or we'll introduce a diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp index c2fc4af..6fbd392 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp @@ -25,7 +25,8 @@ namespace { // member function are matched directly with InnerMatcher. AST_MATCHER_P(FunctionDecl, isInstantiatedFrom, Matcher<FunctionDecl>, InnerMatcher) { - FunctionDecl *InstantiatedFrom = Node.getInstantiatedFromMemberFunction(); + const FunctionDecl *InstantiatedFrom = + Node.getInstantiatedFromMemberFunction(); return InnerMatcher.matches(InstantiatedFrom ? *InstantiatedFrom : Node, Finder, Builder); } diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index efb5ec6..b2e08fe 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -19,6 +19,7 @@ #include "../utils/ExprSequence.h" #include "../utils/Matchers.h" +#include "../utils/OptionsUtils.h" #include <optional> using namespace clang::ast_matchers; @@ -48,7 +49,8 @@ struct UseAfterMove { /// various internal helper functions). class UseAfterMoveFinder { public: - UseAfterMoveFinder(ASTContext *TheContext); + UseAfterMoveFinder(ASTContext *TheContext, + llvm::ArrayRef<StringRef> InvalidationFunctions); // Within the given code block, finds the first use of 'MovedVariable' that // occurs after 'MovingCall' (the expression that performs the move). If a @@ -71,6 +73,7 @@ private: llvm::SmallPtrSetImpl<const DeclRefExpr *> *DeclRefs); ASTContext *Context; + llvm::ArrayRef<StringRef> InvalidationFunctions; std::unique_ptr<ExprSequence> Sequence; std::unique_ptr<StmtToBlockMap> BlockMap; llvm::SmallPtrSet<const CFGBlock *, 8> Visited; @@ -78,6 +81,11 @@ private: } // namespace +static auto getNameMatcher(llvm::ArrayRef<StringRef> InvalidationFunctions) { + return anyOf(hasAnyName("::std::move", "::std::forward"), + matchers::matchesAnyListedName(InvalidationFunctions)); +} + // Matches nodes that are // - Part of a decltype argument or class template argument (we check this by // seeing if they are children of a TypeLoc), or @@ -92,8 +100,9 @@ static StatementMatcher inDecltypeOrTemplateArg() { hasAncestor(expr(hasUnevaluatedContext()))); } -UseAfterMoveFinder::UseAfterMoveFinder(ASTContext *TheContext) - : Context(TheContext) {} +UseAfterMoveFinder::UseAfterMoveFinder( + ASTContext *TheContext, llvm::ArrayRef<StringRef> InvalidationFunctions) + : Context(TheContext), InvalidationFunctions(InvalidationFunctions) {} std::optional<UseAfterMove> UseAfterMoveFinder::find(Stmt *CodeBlock, const Expr *MovingCall, @@ -255,7 +264,7 @@ static bool isStandardSmartPointer(const ValueDecl *VD) { if (!ID) return false; - StringRef Name = ID->getName(); + const StringRef Name = ID->getName(); if (Name != "unique_ptr" && Name != "shared_ptr" && Name != "weak_ptr") return false; @@ -359,7 +368,7 @@ void UseAfterMoveFinder::getReinits( unless(parmVarDecl(hasType( references(qualType(isConstQualified())))))), unless(callee(functionDecl( - hasAnyName("::std::move", "::std::forward"))))))) + getNameMatcher(InvalidationFunctions))))))) .bind("reinit"); Stmts->clear(); @@ -369,7 +378,7 @@ void UseAfterMoveFinder::getReinits( if (!S) continue; - SmallVector<BoundNodes, 1> Matches = + const SmallVector<BoundNodes, 1> Matches = match(findAll(ReinitMatcher), *S->getStmt(), *Context); for (const auto &Match : Matches) { @@ -388,18 +397,21 @@ void UseAfterMoveFinder::getReinits( } } -enum class MoveType { - Move, // std::move - Forward, // std::forward +enum MoveType { + Forward = 0, // std::forward + Move = 1, // std::move + Invalidation = 2, // other }; static MoveType determineMoveType(const FunctionDecl *FuncDecl) { - if (FuncDecl->getName() == "move") - return MoveType::Move; - if (FuncDecl->getName() == "forward") - return MoveType::Forward; + if (FuncDecl->isInStdNamespace()) { + if (FuncDecl->getName() == "move") + return MoveType::Move; + if (FuncDecl->getName() == "forward") + return MoveType::Forward; + } - llvm_unreachable("Invalid move type"); + return MoveType::Invalidation; } static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg, @@ -408,29 +420,38 @@ static void emitDiagnostic(const Expr *MovingCall, const DeclRefExpr *MoveArg, const SourceLocation UseLoc = Use.DeclRef->getExprLoc(); const SourceLocation MoveLoc = MovingCall->getExprLoc(); - const bool IsMove = (Type == MoveType::Move); - - Check->diag(UseLoc, "'%0' used after it was %select{forwarded|moved}1") - << MoveArg->getDecl()->getName() << IsMove; - Check->diag(MoveLoc, "%select{forward|move}0 occurred here", + Check->diag(UseLoc, + "'%0' used after it was %select{forwarded|moved|invalidated}1") + << MoveArg->getDecl()->getName() << Type; + Check->diag(MoveLoc, "%select{forward|move|invalidation}0 occurred here", DiagnosticIDs::Note) - << IsMove; + << Type; if (Use.EvaluationOrderUndefined) { Check->diag( UseLoc, - "the use and %select{forward|move}0 are unsequenced, i.e. " + "the use and %select{forward|move|invalidation}0 are unsequenced, i.e. " "there is no guarantee about the order in which they are evaluated", DiagnosticIDs::Note) - << IsMove; + << Type; } else if (Use.UseHappensInLaterLoopIteration) { Check->diag(UseLoc, "the use happens in a later loop iteration than the " - "%select{forward|move}0", + "%select{forward|move|invalidation}0", DiagnosticIDs::Note) - << IsMove; + << Type; } } +UseAfterMoveCheck::UseAfterMoveCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + InvalidationFunctions(utils::options::parseStringList( + Options.get("InvalidationFunctions", ""))) {} + +void UseAfterMoveCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "InvalidationFunctions", + utils::options::serializeStringList(InvalidationFunctions)); +} + void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) { // try_emplace is a common maybe-moving function that returns a // bool to tell callers whether it moved. Ignore std::move inside @@ -438,11 +459,14 @@ void UseAfterMoveCheck::registerMatchers(MatchFinder *Finder) { // the bool. auto TryEmplaceMatcher = cxxMemberCallExpr(callee(cxxMethodDecl(hasName("try_emplace")))); + auto Arg = declRefExpr().bind("arg"); + auto IsMemberCallee = callee(functionDecl(unless(isStaticStorageClass()))); auto CallMoveMatcher = - callExpr(argumentCountIs(1), - callee(functionDecl(hasAnyName("::std::move", "::std::forward")) + callExpr(callee(functionDecl(getNameMatcher(InvalidationFunctions)) .bind("move-decl")), - hasArgument(0, declRefExpr().bind("arg")), + anyOf(cxxMemberCallExpr(IsMemberCallee, on(Arg)), + callExpr(unless(cxxMemberCallExpr(IsMemberCallee)), + hasArgument(0, Arg))), unless(inDecltypeOrTemplateArg()), unless(hasParent(TryEmplaceMatcher)), expr().bind("call-move"), anyOf(hasAncestor(compoundStmt( @@ -506,7 +530,7 @@ void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) { if (ContainingCtorInit) { // Collect the constructor initializer expressions. bool BeforeMove{true}; - for (CXXCtorInitializer *Init : ContainingCtor->inits()) { + for (const CXXCtorInitializer *Init : ContainingCtor->inits()) { if (BeforeMove && Init->getInit()->IgnoreImplicit() == ContainingCtorInit->IgnoreImplicit()) BeforeMove = false; @@ -521,7 +545,7 @@ void UseAfterMoveCheck::check(const MatchFinder::MatchResult &Result) { } for (Stmt *CodeBlock : CodeBlocks) { - UseAfterMoveFinder Finder(Result.Context); + UseAfterMoveFinder Finder(Result.Context, InvalidationFunctions); if (auto Use = Finder.find(CodeBlock, MovingCall, Arg)) emitDiagnostic(MovingCall, Arg, *Use, this, Result.Context, determineMoveType(MoveDecl)); diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.h b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.h index d38b29e..1bbf5c0 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.h @@ -20,13 +20,16 @@ namespace clang::tidy::bugprone { /// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/use-after-move.html class UseAfterMoveCheck : public ClangTidyCheck { public: - UseAfterMoveCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + UseAfterMoveCheck(StringRef Name, ClangTidyContext *Context); + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus11; } void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + std::vector<StringRef> InvalidationFunctions; }; } // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp index cef8b4d..0d69b9f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/VirtualNearMissCheck.cpp @@ -37,14 +37,14 @@ static bool isOverrideMethod(const CXXMethodDecl *MD) { static bool checkOverridingFunctionReturnType(const ASTContext *Context, const CXXMethodDecl *BaseMD, const CXXMethodDecl *DerivedMD) { - QualType BaseReturnTy = BaseMD->getType() - ->castAs<FunctionType>() - ->getReturnType() - .getCanonicalType(); - QualType DerivedReturnTy = DerivedMD->getType() - ->castAs<FunctionType>() - ->getReturnType() - .getCanonicalType(); + const QualType BaseReturnTy = BaseMD->getType() + ->castAs<FunctionType>() + ->getReturnType() + .getCanonicalType(); + const QualType DerivedReturnTy = DerivedMD->getType() + ->castAs<FunctionType>() + ->getReturnType() + .getCanonicalType(); if (DerivedReturnTy->isDependentType() || BaseReturnTy->isDependentType()) return false; @@ -63,8 +63,8 @@ static bool checkOverridingFunctionReturnType(const ASTContext *Context, /// BTy is the class type in return type of BaseMD. For example, /// B* Base::md() /// While BRD is the declaration of B. - QualType DTy = DerivedReturnTy->getPointeeType().getCanonicalType(); - QualType BTy = BaseReturnTy->getPointeeType().getCanonicalType(); + const QualType DTy = DerivedReturnTy->getPointeeType().getCanonicalType(); + const QualType BTy = BaseReturnTy->getPointeeType().getCanonicalType(); const CXXRecordDecl *DRD = DTy->getAsCXXRecordDecl(); const CXXRecordDecl *BRD = BTy->getAsCXXRecordDecl(); @@ -94,7 +94,7 @@ static bool checkOverridingFunctionReturnType(const ASTContext *Context, // Check accessibility. // FIXME: We currently only support checking if B is accessible base class // of D, or D is the same class which DerivedMD is in. - bool IsItself = + const bool IsItself = DRD->getCanonicalDecl() == DerivedMD->getParent()->getCanonicalDecl(); bool HasPublicAccess = false; for (const auto &Path : Paths) { @@ -129,8 +129,8 @@ static QualType getDecayedType(QualType Type) { /// \returns true if the param types are the same. static bool checkParamTypes(const CXXMethodDecl *BaseMD, const CXXMethodDecl *DerivedMD) { - unsigned NumParamA = BaseMD->getNumParams(); - unsigned NumParamB = DerivedMD->getNumParams(); + const unsigned NumParamA = BaseMD->getNumParams(); + const unsigned NumParamB = DerivedMD->getNumParams(); if (NumParamA != NumParamB) return false; @@ -184,10 +184,10 @@ bool VirtualNearMissCheck::isPossibleToBeOverridden( if (!Inserted) return Iter->second; - bool IsPossible = !BaseMD->isImplicit() && !isa<CXXConstructorDecl>(BaseMD) && - !isa<CXXDestructorDecl>(BaseMD) && BaseMD->isVirtual() && - !BaseMD->isOverloadedOperator() && - !isa<CXXConversionDecl>(BaseMD); + const bool IsPossible = + !BaseMD->isImplicit() && !isa<CXXConstructorDecl>(BaseMD) && + !isa<CXXDestructorDecl>(BaseMD) && BaseMD->isVirtual() && + !BaseMD->isOverloadedOperator() && !isa<CXXConversionDecl>(BaseMD); Iter->second = IsPossible; return IsPossible; } @@ -241,7 +241,7 @@ void VirtualNearMissCheck::check(const MatchFinder::MatchResult &Result) { if (isOverriddenByDerivedClass(BaseMD, DerivedRD)) continue; - unsigned EditDistance = BaseMD->getName().edit_distance( + const unsigned EditDistance = BaseMD->getName().edit_distance( DerivedMD->getName(), EditDistanceThreshold); if (EditDistance > 0 && EditDistance <= EditDistanceThreshold) { if (checkOverrideWithoutName(Context, BaseMD, DerivedMD)) { @@ -249,8 +249,8 @@ void VirtualNearMissCheck::check(const MatchFinder::MatchResult &Result) { auto Range = CharSourceRange::getTokenRange( SourceRange(DerivedMD->getLocation())); - bool ApplyFix = !BaseMD->isTemplateInstantiation() && - !DerivedMD->isTemplateInstantiation(); + const bool ApplyFix = !BaseMD->isTemplateInstantiation() && + !DerivedMD->isTemplateInstantiation(); auto Diag = diag(DerivedMD->getBeginLoc(), "method '%0' has a similar name and the same signature as " diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp index b0799da..16d4be98 100644 --- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp @@ -13,8 +13,10 @@ #include "../bugprone/CommandProcessorCheck.h" #include "../bugprone/CopyConstructorMutatesArgumentCheck.h" #include "../bugprone/DefaultOperatorNewOnOveralignedTypeCheck.h" +#include "../bugprone/ExceptionCopyConstructorThrowsCheck.h" #include "../bugprone/FloatLoopCounterCheck.h" #include "../bugprone/PointerArithmeticOnPolymorphicObjectCheck.h" +#include "../bugprone/RandomGeneratorSeedCheck.h" #include "../bugprone/RawMemoryCallOnNonTrivialTypeCheck.h" #include "../bugprone/ReservedIdentifierCheck.h" #include "../bugprone/SignalHandlerCheck.h" @@ -31,7 +33,8 @@ #include "../concurrency/ThreadCanceltypeAsynchronousCheck.h" #include "../google/UnnamedNamespaceInHeaderCheck.h" #include "../misc/NewDeleteOverloadsCheck.h" -#include "../misc/NonCopyableObjects.h" +#include "../misc/NonCopyableObjectsCheck.h" +#include "../misc/PredictableRandCheck.h" #include "../misc/StaticAssertCheck.h" #include "../misc/ThrowByValueCatchByReferenceCheck.h" #include "../modernize/AvoidSetjmpLongjmpCheck.h" @@ -39,9 +42,6 @@ #include "../performance/MoveConstructorInitCheck.h" #include "../readability/EnumInitialValueCheck.h" #include "../readability/UppercaseLiteralSuffixCheck.h" -#include "LimitedRandomnessCheck.h" -#include "ProperlySeededRandomGeneratorCheck.h" -#include "ThrownExceptionTypeCheck.h" namespace { @@ -262,7 +262,8 @@ public: "cert-err52-cpp"); CheckFactories.registerCheck<bugprone::ThrowingStaticInitializationCheck>( "cert-err58-cpp"); - CheckFactories.registerCheck<ThrownExceptionTypeCheck>("cert-err60-cpp"); + CheckFactories.registerCheck<bugprone::ExceptionCopyConstructorThrowsCheck>( + "cert-err60-cpp"); CheckFactories.registerCheck<misc::ThrowByValueCatchByReferenceCheck>( "cert-err61-cpp"); // MEM @@ -270,8 +271,8 @@ public: .registerCheck<bugprone::DefaultOperatorNewOnOveralignedTypeCheck>( "cert-mem57-cpp"); // MSC - CheckFactories.registerCheck<LimitedRandomnessCheck>("cert-msc50-cpp"); - CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>( + CheckFactories.registerCheck<misc::PredictableRandCheck>("cert-msc50-cpp"); + CheckFactories.registerCheck<bugprone::RandomGeneratorSeedCheck>( "cert-msc51-cpp"); CheckFactories.registerCheck<bugprone::SignalHandlerCheck>( "cert-msc54-cpp"); @@ -323,8 +324,8 @@ public: // MSC CheckFactories.registerCheck<bugprone::UnsafeFunctionsCheck>( "cert-msc24-c"); - CheckFactories.registerCheck<LimitedRandomnessCheck>("cert-msc30-c"); - CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>( + CheckFactories.registerCheck<misc::PredictableRandCheck>("cert-msc30-c"); + CheckFactories.registerCheck<bugprone::RandomGeneratorSeedCheck>( "cert-msc32-c"); CheckFactories.registerCheck<bugprone::UnsafeFunctionsCheck>( "cert-msc33-c"); diff --git a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt index 5abb472..3137903 100644 --- a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt @@ -5,9 +5,6 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangTidyCERTModule STATIC CERTTidyModule.cpp - LimitedRandomnessCheck.cpp - ProperlySeededRandomGeneratorCheck.cpp - ThrownExceptionTypeCheck.cpp LINK_LIBS clangTidy diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt index 0abb000..4b3330d 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -21,7 +21,7 @@ add_clang_library(clangTidyCppCoreGuidelinesModule STATIC OwningMemoryCheck.cpp PreferMemberInitializerCheck.cpp ProBoundsArrayToPointerDecayCheck.cpp - ProBoundsAvoidUncheckedContainerAccess.cpp + ProBoundsAvoidUncheckedContainerAccessCheck.cpp ProBoundsConstantArrayIndexCheck.cpp ProBoundsPointerArithmeticCheck.cpp ProTypeConstCastCheck.cpp diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp index 5f4c9b4..6663955 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -36,7 +36,7 @@ #include "OwningMemoryCheck.h" #include "PreferMemberInitializerCheck.h" #include "ProBoundsArrayToPointerDecayCheck.h" -#include "ProBoundsAvoidUncheckedContainerAccess.h" +#include "ProBoundsAvoidUncheckedContainerAccessCheck.h" #include "ProBoundsConstantArrayIndexCheck.h" #include "ProBoundsPointerArithmeticCheck.h" #include "ProTypeConstCastCheck.h" @@ -108,7 +108,7 @@ public: "cppcoreguidelines-prefer-member-initializer"); CheckFactories.registerCheck<ProBoundsArrayToPointerDecayCheck>( "cppcoreguidelines-pro-bounds-array-to-pointer-decay"); - CheckFactories.registerCheck<ProBoundsAvoidUncheckedContainerAccess>( + CheckFactories.registerCheck<ProBoundsAvoidUncheckedContainerAccessCheck>( "cppcoreguidelines-pro-bounds-avoid-unchecked-container-access"); CheckFactories.registerCheck<ProBoundsConstantArrayIndexCheck>( "cppcoreguidelines-pro-bounds-constant-array-index"); diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp index d0f8652..1c5c854 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp @@ -19,10 +19,11 @@ namespace clang::tidy::cppcoreguidelines { namespace { AST_MATCHER_P(CXXForRangeStmt, hasRangeBeginEndStmt, ast_matchers::internal::Matcher<DeclStmt>, InnerMatcher) { - for (const DeclStmt *Stmt : {Node.getBeginStmt(), Node.getEndStmt()}) - if (Stmt != nullptr && InnerMatcher.matches(*Stmt, Finder, Builder)) - return true; - return false; + return llvm::any_of(llvm::ArrayRef{Node.getBeginStmt(), Node.getEndStmt()}, + [&](const DeclStmt *Stmt) { + return Stmt && + InnerMatcher.matches(*Stmt, Finder, Builder); + }); } AST_MATCHER(Stmt, isInsideOfRangeBeginEndStmt) { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsAvoidUncheckedContainerAccess.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsAvoidUncheckedContainerAccessCheck.cpp index dd7b2b5..cf4b445 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsAvoidUncheckedContainerAccess.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsAvoidUncheckedContainerAccessCheck.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "ProBoundsAvoidUncheckedContainerAccess.h" +#include "ProBoundsAvoidUncheckedContainerAccessCheck.h" #include "../utils/Matchers.h" #include "../utils/OptionsUtils.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -19,8 +19,9 @@ namespace clang::tidy::cppcoreguidelines { static constexpr llvm::StringRef DefaultExclusionStr = "::std::map;::std::unordered_map;::std::flat_map"; -ProBoundsAvoidUncheckedContainerAccess::ProBoundsAvoidUncheckedContainerAccess( - StringRef Name, ClangTidyContext *Context) +ProBoundsAvoidUncheckedContainerAccessCheck:: + ProBoundsAvoidUncheckedContainerAccessCheck(StringRef Name, + ClangTidyContext *Context) : ClangTidyCheck(Name, Context), ExcludedClasses(utils::options::parseStringList( Options.get("ExcludeClasses", DefaultExclusionStr))), @@ -28,7 +29,7 @@ ProBoundsAvoidUncheckedContainerAccess::ProBoundsAvoidUncheckedContainerAccess( FixFunction(Options.get("FixFunction", "gsl::at")), FixFunctionEmptyArgs(Options.get("FixFunctionEmptyArgs", FixFunction)) {} -void ProBoundsAvoidUncheckedContainerAccess::storeOptions( +void ProBoundsAvoidUncheckedContainerAccessCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "ExcludeClasses", utils::options::serializeStringList(ExcludedClasses)); @@ -86,7 +87,7 @@ findAlternativeAt(const CXXMethodDecl *MatchedOperator) { return nullptr; } -void ProBoundsAvoidUncheckedContainerAccess::registerMatchers( +void ProBoundsAvoidUncheckedContainerAccessCheck::registerMatchers( MatchFinder *Finder) { Finder->addMatcher( mapAnyOf(cxxOperatorCallExpr, cxxMemberCallExpr) @@ -100,9 +101,8 @@ void ProBoundsAvoidUncheckedContainerAccess::registerMatchers( this); } -void ProBoundsAvoidUncheckedContainerAccess::check( +void ProBoundsAvoidUncheckedContainerAccessCheck::check( const MatchFinder::MatchResult &Result) { - const auto *MatchedExpr = Result.Nodes.getNodeAs<CallExpr>("caller"); if (FixMode == None) { @@ -176,7 +176,7 @@ void ProBoundsAvoidUncheckedContainerAccess::check( } } else if (const auto *MCE = dyn_cast<CXXMemberCallExpr>(MatchedExpr)) { // Case: a.operator[](i) or a->operator[](i) - const auto *Callee = dyn_cast<MemberExpr>(MCE->getCallee()); + const auto *Callee = cast<MemberExpr>(MCE->getCallee()); if (FixMode == At) { // Cases: a.operator[](i) => a.at(i) and a->operator[](i) => a->at(i) @@ -251,7 +251,7 @@ void ProBoundsAvoidUncheckedContainerAccess::check( } // namespace clang::tidy::cppcoreguidelines namespace clang::tidy { -using P = cppcoreguidelines::ProBoundsAvoidUncheckedContainerAccess; +using P = cppcoreguidelines::ProBoundsAvoidUncheckedContainerAccessCheck; llvm::ArrayRef<std::pair<P::FixModes, StringRef>> OptionEnumMapping<P::FixModes>::getEnumMapping() { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsAvoidUncheckedContainerAccess.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsAvoidUncheckedContainerAccessCheck.h index 2462e7a..85b5a93 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsAvoidUncheckedContainerAccess.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProBoundsAvoidUncheckedContainerAccessCheck.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PROBOUNDSAVOIDUNCHECKEDCONTAINERACCESS_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PROBOUNDSAVOIDUNCHECKEDCONTAINERACCESS_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PROBOUNDSAVOIDUNCHECKEDCONTAINERACCESSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PROBOUNDSAVOIDUNCHECKEDCONTAINERACCESSCHECK_H #include "../ClangTidyCheck.h" @@ -20,10 +20,10 @@ namespace clang::tidy::cppcoreguidelines { /// https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#slcon3-avoid-bounds-errors /// For the user-facing documentation see: /// https://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines/pro-bounds-avoid-unchecked-container-access.html -class ProBoundsAvoidUncheckedContainerAccess : public ClangTidyCheck { +class ProBoundsAvoidUncheckedContainerAccessCheck : public ClangTidyCheck { public: - ProBoundsAvoidUncheckedContainerAccess(StringRef Name, - ClangTidyContext *Context); + ProBoundsAvoidUncheckedContainerAccessCheck(StringRef Name, + ClangTidyContext *Context); bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus; } @@ -46,11 +46,11 @@ private: namespace clang::tidy { template <> struct OptionEnumMapping< - cppcoreguidelines::ProBoundsAvoidUncheckedContainerAccess::FixModes> { + cppcoreguidelines::ProBoundsAvoidUncheckedContainerAccessCheck::FixModes> { static ArrayRef<std::pair< - cppcoreguidelines::ProBoundsAvoidUncheckedContainerAccess::FixModes, + cppcoreguidelines::ProBoundsAvoidUncheckedContainerAccessCheck::FixModes, StringRef>> getEnumMapping(); }; } // namespace clang::tidy -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PROBOUNDSAVOIDUNCHECKEDCONTAINERACCESS_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PROBOUNDSAVOIDUNCHECKEDCONTAINERACCESSCHECK_H diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp index 111c621..f267646 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -361,7 +361,8 @@ void ProTypeMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } // FIXME: Copied from clang/lib/Sema/SemaDeclCXX.cpp. -static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) { +static bool isIncompleteOrZeroLengthArrayType(const ASTContext &Context, + QualType T) { if (T->isIncompleteArrayType()) return true; @@ -375,7 +376,7 @@ static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) { return false; } -static bool isEmpty(ASTContext &Context, const QualType &Type) { +static bool isEmpty(const ASTContext &Context, const QualType &Type) { if (const CXXRecordDecl *ClassDecl = Type->getAsCXXRecordDecl()) { return ClassDecl->isEmpty(); } @@ -431,19 +432,13 @@ static llvm::StringLiteral getInitializer(QualType QT, bool UseAssignment) { } } -void ProTypeMemberInitCheck::checkMissingMemberInitializer( - ASTContext &Context, const CXXRecordDecl &ClassDecl, - const CXXConstructorDecl *Ctor) { - const bool IsUnion = ClassDecl.isUnion(); - - if (IsUnion && ClassDecl.hasInClassInitializer()) - return; - - // Gather all fields (direct and indirect) that need to be initialized. - SmallPtrSet<const FieldDecl *, 16> FieldsToInit; +static void +computeFieldsToInit(const ASTContext &Context, const RecordDecl &Record, + bool IgnoreArrays, + SmallPtrSetImpl<const FieldDecl *> &FieldsToInit) { bool AnyMemberHasInitPerUnion = false; forEachFieldWithFilter( - ClassDecl, ClassDecl.fields(), AnyMemberHasInitPerUnion, + Record, Record.fields(), AnyMemberHasInitPerUnion, [&](const FieldDecl *F) { if (IgnoreArrays && F->getType()->isArrayType()) return; @@ -458,6 +453,19 @@ void ProTypeMemberInitCheck::checkMissingMemberInitializer( !AnyMemberHasInitPerUnion) FieldsToInit.insert(F); }); +} + +void ProTypeMemberInitCheck::checkMissingMemberInitializer( + ASTContext &Context, const CXXRecordDecl &ClassDecl, + const CXXConstructorDecl *Ctor) { + const bool IsUnion = ClassDecl.isUnion(); + + if (IsUnion && ClassDecl.hasInClassInitializer()) + return; + + // Gather all fields (direct and indirect) that need to be initialized. + SmallPtrSet<const FieldDecl *, 16> FieldsToInit; + computeFieldsToInit(Context, ClassDecl, IgnoreArrays, FieldsToInit); if (FieldsToInit.empty()) return; @@ -507,7 +515,7 @@ void ProTypeMemberInitCheck::checkMissingMemberInitializer( // Collect all fields but only suggest a fix for the first member of unions, // as initializing more than one union member is an error. SmallPtrSet<const FieldDecl *, 16> FieldsToFix; - AnyMemberHasInitPerUnion = false; + bool AnyMemberHasInitPerUnion = false; forEachFieldWithFilter(ClassDecl, ClassDecl.fields(), AnyMemberHasInitPerUnion, [&](const FieldDecl *F) { if (!FieldsToInit.contains(F)) @@ -541,7 +549,6 @@ void ProTypeMemberInitCheck::checkMissingMemberInitializer( void ProTypeMemberInitCheck::checkMissingBaseClassInitializer( const ASTContext &Context, const CXXRecordDecl &ClassDecl, const CXXConstructorDecl *Ctor) { - // Gather any base classes that need to be initialized. SmallVector<const RecordDecl *, 4> AllBases; SmallPtrSet<const RecordDecl *, 4> BasesToInit; @@ -583,6 +590,17 @@ void ProTypeMemberInitCheck::checkMissingBaseClassInitializer( void ProTypeMemberInitCheck::checkUninitializedTrivialType( const ASTContext &Context, const VarDecl *Var) { + // Verify that the record actually needs initialization + const CXXRecordDecl *Record = Var->getType()->getAsCXXRecordDecl(); + if (!Record) + return; + + SmallPtrSet<const FieldDecl *, 16> FieldsToInit; + computeFieldsToInit(Context, *Record, IgnoreArrays, FieldsToInit); + + if (FieldsToInit.empty()) + return; + const DiagnosticBuilder Diag = diag(Var->getBeginLoc(), "uninitialized record type: %0") << Var; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp index 77a7b2b..851392f 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp @@ -102,7 +102,6 @@ toString(SpecialMemberFunctionsCheck::SpecialMemberFunctionKind K) { static std::string join(ArrayRef<SpecialMemberFunctionsCheck::SpecialMemberFunctionKind> SMFS, llvm::StringRef AndOr) { - assert(!SMFS.empty() && "List of defined or undefined members should never be empty."); std::string Buffer; diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h index 1d41b57..6d76e07 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h @@ -93,7 +93,7 @@ struct DenseMapInfo< "TOMBSTONE"}; } - static unsigned getHashValue(ClassDefId Val) { + static unsigned getHashValue(const ClassDefId &Val) { assert(Val != getEmptyKey() && "Cannot hash the empty key!"); assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!"); diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp index 89f1bf1..bfa9ce3 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp @@ -167,7 +167,6 @@ static FixItHint changePrivateDestructorVisibilityTo( void VirtualClassDestructorCheck::check( const MatchFinder::MatchResult &Result) { - const auto *MatchedClassOrStruct = Result.Nodes.getNodeAs<CXXRecordDecl>("ProblematicClassOrStruct"); diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp index 652dec9..4a10cb4 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp @@ -17,113 +17,61 @@ namespace clang::tidy::fuchsia { namespace { AST_MATCHER(CXXRecordDecl, hasBases) { - if (Node.hasDefinition()) - return Node.getNumBases() > 0; - return false; + return Node.hasDefinition() && Node.getNumBases() > 0; } } // namespace -// Adds a node (by name) to the interface map, if it was not present in the map -// previously. -void MultipleInheritanceCheck::addNodeToInterfaceMap(const CXXRecordDecl *Node, - bool IsInterface) { - assert(Node->getIdentifier()); - const StringRef Name = Node->getIdentifier()->getName(); - InterfaceMap.insert(std::make_pair(Name, IsInterface)); -} - -// Returns "true" if the boolean "isInterface" has been set to the -// interface status of the current Node. Return "false" if the -// interface status for the current node is not yet known. -bool MultipleInheritanceCheck::getInterfaceStatus(const CXXRecordDecl *Node, - bool &IsInterface) const { - assert(Node->getIdentifier()); - const StringRef Name = Node->getIdentifier()->getName(); - auto Pair = InterfaceMap.find(Name); - if (Pair == InterfaceMap.end()) - return false; - IsInterface = Pair->second; - return true; -} - -bool MultipleInheritanceCheck::isCurrentClassInterface( - const CXXRecordDecl *Node) const { - // Interfaces should have no fields. - if (!Node->field_empty()) - return false; - - // Interfaces should have exclusively pure methods. - return llvm::none_of(Node->methods(), [](const CXXMethodDecl *M) { - return M->isUserProvided() && !M->isPureVirtual() && !M->isStatic(); - }); -} +bool MultipleInheritanceCheck::isInterface(const CXXBaseSpecifier &Base) { + const CXXRecordDecl *const Node = Base.getType()->getAsCXXRecordDecl(); + if (!Node) + return true; -bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) { - if (!Node->getIdentifier()) - return false; + assert(Node->isCompleteDefinition()); // Short circuit the lookup if we have analyzed this record before. - bool PreviousIsInterfaceResult = false; - if (getInterfaceStatus(Node, PreviousIsInterfaceResult)) - return PreviousIsInterfaceResult; - - // To be an interface, all base classes must be interfaces as well. - for (const auto &I : Node->bases()) { - if (I.isVirtual()) - continue; - const auto *Base = I.getType()->getAsCXXRecordDecl(); - if (!Base) - continue; - assert(Base->isCompleteDefinition()); - if (!isInterface(Base)) { - addNodeToInterfaceMap(Node, false); - return false; - } - } - - const bool CurrentClassIsInterface = isCurrentClassInterface(Node); - addNodeToInterfaceMap(Node, CurrentClassIsInterface); + if (const auto CachedValue = InterfaceMap.find(Node); + CachedValue != InterfaceMap.end()) + return CachedValue->second; + + // To be an interface, a class must have... + const bool CurrentClassIsInterface = + // ...no bases that aren't interfaces... + llvm::none_of(Node->bases(), + [&](const CXXBaseSpecifier &I) { + return !I.isVirtual() && !isInterface(I); + }) && + // ...no fields, and... + Node->field_empty() && + // ...no methods that aren't pure virtual. + llvm::none_of(Node->methods(), [](const CXXMethodDecl *M) { + return M->isUserProvided() && !M->isPureVirtual() && !M->isStatic(); + }); + + InterfaceMap.try_emplace(Node, CurrentClassIsInterface); return CurrentClassIsInterface; } void MultipleInheritanceCheck::registerMatchers(MatchFinder *Finder) { - // Match declarations which have bases. Finder->addMatcher(cxxRecordDecl(hasBases(), isDefinition()).bind("decl"), this); } void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) { - if (const auto *D = Result.Nodes.getNodeAs<CXXRecordDecl>("decl")) { - // Check against map to see if the class inherits from multiple - // concrete classes - unsigned NumConcrete = 0; - for (const auto &I : D->bases()) { - if (I.isVirtual()) - continue; - const auto *Base = I.getType()->getAsCXXRecordDecl(); - if (!Base) - continue; - assert(Base->isCompleteDefinition()); - if (!isInterface(Base)) - NumConcrete++; - } - - // Check virtual bases to see if there is more than one concrete - // non-virtual base. - for (const auto &V : D->vbases()) { - const auto *Base = V.getType()->getAsCXXRecordDecl(); - if (!Base) - continue; - assert(Base->isCompleteDefinition()); - if (!isInterface(Base)) - NumConcrete++; - } - - if (NumConcrete > 1) { - diag(D->getBeginLoc(), "inheriting multiple classes that aren't " - "pure virtual is discouraged"); - } - } + const auto &D = *Result.Nodes.getNodeAs<CXXRecordDecl>("decl"); + // Check to see if the class inherits from multiple concrete classes. + unsigned NumConcrete = + llvm::count_if(D.bases(), [&](const CXXBaseSpecifier &I) { + return !I.isVirtual() && !isInterface(I); + }); + + // Check virtual bases to see if there is more than one concrete + // non-virtual base. + NumConcrete += llvm::count_if( + D.vbases(), [&](const CXXBaseSpecifier &V) { return !isInterface(V); }); + + if (NumConcrete > 1) + diag(D.getBeginLoc(), "inheriting multiple classes that aren't " + "pure virtual is discouraged"); } } // namespace clang::tidy::fuchsia diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h index 2e26843..4dcbd0c 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h +++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h @@ -30,15 +30,12 @@ public: void onEndOfTranslationUnit() override { InterfaceMap.clear(); } private: - void addNodeToInterfaceMap(const CXXRecordDecl *Node, bool IsInterface); - bool getInterfaceStatus(const CXXRecordDecl *Node, bool &IsInterface) const; - bool isCurrentClassInterface(const CXXRecordDecl *Node) const; - bool isInterface(const CXXRecordDecl *Node); + bool isInterface(const CXXBaseSpecifier &Base); // Contains the identity of each named CXXRecord as an interface. This is // used to memoize lookup speeds and improve performance from O(N^2) to O(N), // where N is the number of classes. - llvm::StringMap<bool> InterfaceMap; + llvm::DenseMap<const CXXRecordDecl *, bool> InterfaceMap; }; } // namespace clang::tidy::fuchsia diff --git a/clang-tools-extra/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp index b6fb22c..9c98b49 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp +++ b/clang-tools-extra/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp @@ -20,10 +20,9 @@ AST_MATCHER(CXXRecordDecl, hasDirectVirtualBaseClass) { return false; if (!Node.getNumVBases()) return false; - for (const CXXBaseSpecifier &Base : Node.bases()) - if (Base.isVirtual()) - return true; - return false; + return llvm::any_of(Node.bases(), [](const CXXBaseSpecifier &Base) { + return Base.isVirtual(); + }); } } // namespace diff --git a/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp b/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp index 6b96f71..92d590c 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp @@ -14,7 +14,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::google::objc { void AvoidThrowingObjCExceptionCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(objcThrowStmt().bind("throwStmt"), this); Finder->addMatcher( objcMessageExpr(anyOf(hasSelector("raise:format:"), diff --git a/clang-tools-extra/clang-tidy/google/CMakeLists.txt b/clang-tools-extra/clang-tidy/google/CMakeLists.txt index 1d4229e..982a188 100644 --- a/clang-tools-extra/clang-tidy/google/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/google/CMakeLists.txt @@ -4,7 +4,6 @@ set(LLVM_LINK_COMPONENTS ) add_clang_library(clangTidyGoogleModule STATIC - AvoidCStyleCastsCheck.cpp AvoidNSObjectNewCheck.cpp AvoidThrowingObjCExceptionCheck.cpp AvoidUnderscoreInGoogletestNameCheck.cpp @@ -25,6 +24,7 @@ add_clang_library(clangTidyGoogleModule STATIC LINK_LIBS clangTidy + clangTidyModernizeModule clangTidyReadabilityModule clangTidyUtils diff --git a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp index aff8b45..ce46b3f 100644 --- a/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp @@ -9,10 +9,10 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" +#include "../modernize/AvoidCStyleCastCheck.h" #include "../readability/BracesAroundStatementsCheck.h" #include "../readability/FunctionSizeCheck.h" #include "../readability/NamespaceCommentCheck.h" -#include "AvoidCStyleCastsCheck.h" #include "AvoidNSObjectNewCheck.h" #include "AvoidThrowingObjCExceptionCheck.h" #include "AvoidUnderscoreInGoogletestNameCheck.h" @@ -67,7 +67,7 @@ public: CheckFactories .registerCheck<readability::AvoidUnderscoreInGoogletestNameCheck>( "google-readability-avoid-underscore-in-googletest-name"); - CheckFactories.registerCheck<readability::AvoidCStyleCastsCheck>( + CheckFactories.registerCheck<modernize::AvoidCStyleCastCheck>( "google-readability-casting"); CheckFactories.registerCheck<readability::TodoCommentCheck>( "google-readability-todo"); diff --git a/clang-tools-extra/clang-tidy/google/TodoCommentCheck.cpp b/clang-tools-extra/clang-tidy/google/TodoCommentCheck.cpp index 7331b36..2789e4d 100644 --- a/clang-tools-extra/clang-tidy/google/TodoCommentCheck.cpp +++ b/clang-tools-extra/clang-tidy/google/TodoCommentCheck.cpp @@ -11,42 +11,102 @@ #include "clang/Lex/Preprocessor.h" #include <optional> -namespace clang::tidy::google::readability { +namespace clang::tidy { + +namespace google::readability { + +enum class StyleKind { Parentheses, Hyphen }; + +} // namespace google::readability + +template <> struct OptionEnumMapping<google::readability::StyleKind> { + static ArrayRef<std::pair<google::readability::StyleKind, StringRef>> + getEnumMapping() { + static constexpr std::pair<google::readability::StyleKind, StringRef> + Mapping[] = { + {google::readability::StyleKind::Hyphen, "Hyphen"}, + {google::readability::StyleKind::Parentheses, "Parentheses"}, + }; + return {Mapping}; + } +}; + +} // namespace clang::tidy +namespace clang::tidy::google::readability { class TodoCommentCheck::TodoCommentHandler : public CommentHandler { public: TodoCommentHandler(TodoCommentCheck &Check, std::optional<std::string> User) : Check(Check), User(User ? *User : "unknown"), - TodoMatch("^// *TODO *(\\(.*\\))?:?( )?(.*)$") {} + TodoMatch(R"(^// *TODO *((\((.*)\))?:?( )?|: *(.*) *- *)?(.*)$)") { + const llvm::StringRef TodoStyleString = + Check.Options.get("Style", "Hyphen"); + for (const auto &[Value, Name] : + OptionEnumMapping<StyleKind>::getEnumMapping()) { + if (Name == TodoStyleString) { + TodoStyle = Value; + return; + } + } + Check.configurationDiag( + "invalid value '%0' for " + "google-readability-todo.Style; valid values are " + "'Parentheses' and 'Hyphen'. Defaulting to 'Hyphen'") + << TodoStyleString; + } bool HandleComment(Preprocessor &PP, SourceRange Range) override { const StringRef Text = Lexer::getSourceText(CharSourceRange::getCharRange(Range), PP.getSourceManager(), PP.getLangOpts()); - SmallVector<StringRef, 4> Matches; + SmallVector<StringRef, 7> Matches; if (!TodoMatch.match(Text, &Matches)) return false; - const StringRef Username = Matches[1]; - const StringRef Comment = Matches[3]; + const StyleKind ParsedStyle = + !Matches[3].empty() ? StyleKind::Parentheses : StyleKind::Hyphen; + const StringRef Username = + ParsedStyle == StyleKind::Parentheses ? Matches[3] : Matches[5]; + const StringRef Comment = Matches[6]; - if (!Username.empty()) + if (!Username.empty() && + (ParsedStyle == StyleKind::Parentheses || !Comment.empty())) { return false; + } - const std::string NewText = - ("// TODO(" + Twine(User) + "): " + Comment).str(); + if (Username.empty()) { + Check.diag(Range.getBegin(), "missing username/bug in TODO") + << FixItHint::CreateReplacement( + CharSourceRange::getCharRange(Range), + createReplacementString(Username, Comment)); + } + + if (Comment.empty()) + Check.diag(Range.getBegin(), "missing details in TODO"); - Check.diag(Range.getBegin(), "missing username/bug in TODO") - << FixItHint::CreateReplacement(CharSourceRange::getCharRange(Range), - NewText); return false; } + std::string createReplacementString(const StringRef Username, + const StringRef Comment) const { + if (TodoStyle == StyleKind::Parentheses) { + return ("// TODO(" + Twine(User) + + "): " + (Comment.empty() ? "some details" : Comment)) + .str(); + } + return ("// TODO: " + Twine(User) + " - " + + (Comment.empty() ? "some details" : Comment)) + .str(); + } + + StyleKind getTodoStyle() const { return TodoStyle; } + private: TodoCommentCheck &Check; std::string User; llvm::Regex TodoMatch; + StyleKind TodoStyle = StyleKind::Hyphen; }; TodoCommentCheck::TodoCommentCheck(StringRef Name, ClangTidyContext *Context) @@ -62,4 +122,8 @@ void TodoCommentCheck::registerPPCallbacks(const SourceManager &SM, PP->addCommentHandler(Handler.get()); } +void TodoCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "Style", Handler->getTodoStyle()); +} + } // namespace clang::tidy::google::readability diff --git a/clang-tools-extra/clang-tidy/google/TodoCommentCheck.h b/clang-tools-extra/clang-tidy/google/TodoCommentCheck.h index 08cea13..800bc0f 100644 --- a/clang-tools-extra/clang-tidy/google/TodoCommentCheck.h +++ b/clang-tools-extra/clang-tidy/google/TodoCommentCheck.h @@ -27,6 +27,8 @@ public: void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + private: class TodoCommentHandler; std::unique_ptr<TodoCommentHandler> Handler; diff --git a/clang-tools-extra/clang-tidy/llvm/PreferStaticOverAnonymousNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/llvm/PreferStaticOverAnonymousNamespaceCheck.cpp index ea81c7c..d720986 100644 --- a/clang-tools-extra/clang-tidy/llvm/PreferStaticOverAnonymousNamespaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/PreferStaticOverAnonymousNamespaceCheck.cpp @@ -77,7 +77,6 @@ void PreferStaticOverAnonymousNamespaceCheck::registerMatchers( void PreferStaticOverAnonymousNamespaceCheck::check( const MatchFinder::MatchResult &Result) { - if (const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("function")) { if (Func->isCXXClassMember()) diag(Func->getLocation(), diff --git a/clang-tools-extra/clang-tidy/llvm/UseNewMLIROpBuilderCheck.cpp b/clang-tools-extra/clang-tidy/llvm/UseNewMLIROpBuilderCheck.cpp index 55b383e..16f8786 100644 --- a/clang-tools-extra/clang-tidy/llvm/UseNewMLIROpBuilderCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvm/UseNewMLIROpBuilderCheck.cpp @@ -12,7 +12,6 @@ #include "clang/Lex/Lexer.h" #include "clang/Tooling/Transformer/RangeSelector.h" #include "clang/Tooling/Transformer/RewriteRule.h" -#include "clang/Tooling/Transformer/SourceCode.h" #include "clang/Tooling/Transformer/Stencil.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" diff --git a/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp b/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp index 129b8a9..ecd8e19 100644 --- a/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/llvmlibc/RestrictSystemLibcHeadersCheck.cpp @@ -22,11 +22,11 @@ namespace { class RestrictedIncludesPPCallbacks : public portability::RestrictedIncludesPPCallbacks { public: - explicit RestrictedIncludesPPCallbacks( - RestrictSystemLibcHeadersCheck &Check, const SourceManager &SM, - const SmallString<128> CompilerIncudeDir) + explicit RestrictedIncludesPPCallbacks(RestrictSystemLibcHeadersCheck &Check, + const SourceManager &SM, + SmallString<128> CompilerIncudeDir) : portability::RestrictedIncludesPPCallbacks(Check, SM), - CompilerIncudeDir(CompilerIncudeDir) {} + CompilerIncudeDir(std::move(CompilerIncudeDir)) {} void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, @@ -61,7 +61,7 @@ void RestrictSystemLibcHeadersCheck::registerPPCallbacks( StringRef(PP->getHeaderSearchInfo().getHeaderSearchOpts().ResourceDir); llvm::sys::path::append(CompilerIncudeDir, "include"); PP->addPPCallbacks(std::make_unique<RestrictedIncludesPPCallbacks>( - *this, SM, CompilerIncudeDir)); + *this, SM, std::move(CompilerIncudeDir))); } } // namespace clang::tidy::llvm_libc diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt index 2cfee5f..e8705aa 100644 --- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt @@ -25,14 +25,15 @@ add_clang_library(clangTidyMiscModule STATIC HeaderIncludeCycleCheck.cpp IncludeCleanerCheck.cpp MiscTidyModule.cpp - MisleadingBidirectional.cpp - MisleadingIdentifier.cpp + MisleadingBidirectionalCheck.cpp + MisleadingIdentifierCheck.cpp MisplacedConstCheck.cpp NewDeleteOverloadsCheck.cpp NoRecursionCheck.cpp - NonCopyableObjects.cpp + NonCopyableObjectsCheck.cpp NonPrivateMemberVariablesInClassesCheck.cpp OverrideWithDifferentVisibilityCheck.cpp + PredictableRandCheck.cpp RedundantExpressionCheck.cpp StaticAssertCheck.cpp ThrowByValueCatchByReferenceCheck.cpp diff --git a/clang-tools-extra/clang-tidy/misc/ConfusableIdentifierCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConfusableIdentifierCheck.cpp index 61d5477..418b8ae 100644 --- a/clang-tools-extra/clang-tidy/misc/ConfusableIdentifierCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/ConfusableIdentifierCheck.cpp @@ -53,7 +53,6 @@ static llvm::SmallString<64U> skeleton(StringRef Name) { const char *Curr = Name.data(); const char *End = Curr + Name.size(); while (Curr < End) { - const char *Prev = Curr; UTF32 CodePoint = 0; const ConversionResult Result = convertUTF8Sequence( @@ -82,7 +81,8 @@ static llvm::SmallString<64U> skeleton(StringRef Name) { errs() << "Unicode conversion issue\n"; break; } - Skeleton.append((char *)BufferStart, (char *)IBuffer); + Skeleton.append(reinterpret_cast<char *>(BufferStart), + reinterpret_cast<char *>(IBuffer)); } } return Skeleton; diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp index a2d3d3f..75693a0 100644 --- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.cpp @@ -67,13 +67,20 @@ static auto typeWithNameIn(const std::vector<StringRef> &Names) { hasCanonicalType(hasDeclaration(namedDecl(hasAnyName(Names))))); } +static auto functionWithNameIn(const std::vector<StringRef> &Names) { + auto Call = callExpr(callee(functionDecl(hasAnyName(Names)))); + return anyOf(expr(cxxBindTemporaryExpr(has(Call))), expr(Call)); +} + CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), RAIITypesList(utils::options::parseStringList( Options.get("RAIITypesList", "std::lock_guard;std::scoped_lock"))), AllowedAwaitablesList(utils::options::parseStringList( - Options.get("AllowedAwaitablesList", ""))) {} + Options.get("AllowedAwaitablesList", ""))), + AllowedCallees( + utils::options::parseStringList(Options.get("AllowedCallees", ""))) {} void CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) { // A suspension happens with co_await or co_yield. @@ -81,7 +88,8 @@ void CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) { hasAttr(attr::Kind::ScopedLockable))))) .bind("scoped-lockable"); auto OtherRAII = varDecl(typeWithNameIn(RAIITypesList)).bind("raii"); - auto AllowedSuspend = awaitable(typeWithNameIn(AllowedAwaitablesList)); + auto AllowedSuspend = awaitable(anyOf(typeWithNameIn(AllowedAwaitablesList), + functionWithNameIn(AllowedCallees))); Finder->addMatcher( expr(anyOf(coawaitExpr(unless(AllowedSuspend)), coyieldExpr()), forEachPrevStmt( @@ -109,7 +117,9 @@ void CoroutineHostileRAIICheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "RAIITypesList", utils::options::serializeStringList(RAIITypesList)); - Options.store(Opts, "SafeAwaitableList", + Options.store(Opts, "AllowedAwaitablesList", utils::options::serializeStringList(AllowedAwaitablesList)); + Options.store(Opts, "AllowedCallees", + utils::options::serializeStringList(AllowedCallees)); } } // namespace clang::tidy::misc diff --git a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.h b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.h index 768b62e..12ad1b1 100644 --- a/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.h +++ b/clang-tools-extra/clang-tidy/misc/CoroutineHostileRAIICheck.h @@ -46,6 +46,9 @@ private: // List of fully qualified awaitable types which are considered safe to // co_await. std::vector<StringRef> AllowedAwaitablesList; + // List of callees whose return values are considered safe to directly + // co_await. + std::vector<StringRef> AllowedCallees; }; } // namespace clang::tidy::misc diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp index 6f4af6c..03f2577 100644 --- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp @@ -15,14 +15,15 @@ #include "DefinitionsInHeadersCheck.h" #include "HeaderIncludeCycleCheck.h" #include "IncludeCleanerCheck.h" -#include "MisleadingBidirectional.h" -#include "MisleadingIdentifier.h" +#include "MisleadingBidirectionalCheck.h" +#include "MisleadingIdentifierCheck.h" #include "MisplacedConstCheck.h" #include "NewDeleteOverloadsCheck.h" #include "NoRecursionCheck.h" -#include "NonCopyableObjects.h" +#include "NonCopyableObjectsCheck.h" #include "NonPrivateMemberVariablesInClassesCheck.h" #include "OverrideWithDifferentVisibilityCheck.h" +#include "PredictableRandCheck.h" #include "RedundantExpressionCheck.h" #include "StaticAssertCheck.h" #include "ThrowByValueCatchByReferenceCheck.h" @@ -63,6 +64,9 @@ public: "misc-non-copyable-objects"); CheckFactories.registerCheck<NonPrivateMemberVariablesInClassesCheck>( "misc-non-private-member-variables-in-classes"); + CheckFactories.registerCheck<OverrideWithDifferentVisibilityCheck>( + "misc-override-with-different-visibility"); + CheckFactories.registerCheck<PredictableRandCheck>("misc-predictable-rand"); CheckFactories.registerCheck<RedundantExpressionCheck>( "misc-redundant-expression"); CheckFactories.registerCheck<StaticAssertCheck>("misc-static-assert"); @@ -82,8 +86,6 @@ public: "misc-use-anonymous-namespace"); CheckFactories.registerCheck<UseInternalLinkageCheck>( "misc-use-internal-linkage"); - CheckFactories.registerCheck<OverrideWithDifferentVisibilityCheck>( - "misc-override-with-different-visibility"); } }; diff --git a/clang-tools-extra/clang-tidy/misc/MisleadingBidirectional.cpp b/clang-tools-extra/clang-tidy/misc/MisleadingBidirectionalCheck.cpp index db5bc61..8a10f70 100644 --- a/clang-tools-extra/clang-tidy/misc/MisleadingBidirectional.cpp +++ b/clang-tools-extra/clang-tidy/misc/MisleadingBidirectionalCheck.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "MisleadingBidirectional.h" +#include "MisleadingBidirectionalCheck.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Preprocessor.h" @@ -52,8 +52,9 @@ static bool containsMisleadingBidi(StringRef Buffer, } llvm::UTF32 CodePoint = 0; const llvm::ConversionResult Result = llvm::convertUTF8Sequence( - (const llvm::UTF8 **)&CurPtr, (const llvm::UTF8 *)Buffer.end(), - &CodePoint, llvm::strictConversion); + reinterpret_cast<const llvm::UTF8 **>(&CurPtr), + reinterpret_cast<const llvm::UTF8 *>(Buffer.end()), &CodePoint, + llvm::strictConversion); // If conversion fails, utf-8 is designed so that we can just try next char. if (Result != llvm::conversionOK) { diff --git a/clang-tools-extra/clang-tidy/misc/MisleadingBidirectional.h b/clang-tools-extra/clang-tidy/misc/MisleadingBidirectionalCheck.h index 50e70cb..7c7577f 100644 --- a/clang-tools-extra/clang-tidy/misc/MisleadingBidirectional.h +++ b/clang-tools-extra/clang-tidy/misc/MisleadingBidirectionalCheck.h @@ -6,13 +6,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGBIDIRECTIONAL_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGBIDIRECTIONAL_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGBIDIRECTIONALCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGBIDIRECTIONALCHECK_H #include "../ClangTidyCheck.h" namespace clang::tidy::misc { +/// Warns about unterminated bidirectional unicode sequence. +/// +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/misc/misleading-bidirectional.html class MisleadingBidirectionalCheck : public ClangTidyCheck { public: MisleadingBidirectionalCheck(StringRef Name, ClangTidyContext *Context); @@ -31,4 +35,4 @@ private: } // namespace clang::tidy::misc -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGBIDIRECTIONAL_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGBIDIRECTIONALCHECK_H diff --git a/clang-tools-extra/clang-tidy/misc/MisleadingIdentifier.cpp b/clang-tools-extra/clang-tidy/misc/MisleadingIdentifierCheck.cpp index 3c8a03a..9c0de87 100644 --- a/clang-tools-extra/clang-tidy/misc/MisleadingIdentifier.cpp +++ b/clang-tools-extra/clang-tidy/misc/MisleadingIdentifierCheck.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "MisleadingIdentifier.h" +#include "MisleadingIdentifierCheck.h" #include "llvm/Support/ConvertUTF.h" @@ -125,7 +125,8 @@ static bool hasRTLCharacters(StringRef Buffer) { while (CurPtr < EndPtr) { llvm::UTF32 CodePoint = 0; const llvm::ConversionResult Result = llvm::convertUTF8Sequence( - (const llvm::UTF8 **)&CurPtr, (const llvm::UTF8 *)EndPtr, &CodePoint, + reinterpret_cast<const llvm::UTF8 **>(&CurPtr), + reinterpret_cast<const llvm::UTF8 *>(EndPtr), &CodePoint, llvm::strictConversion); if (Result != llvm::conversionOK) break; diff --git a/clang-tools-extra/clang-tidy/misc/MisleadingIdentifier.h b/clang-tools-extra/clang-tidy/misc/MisleadingIdentifierCheck.h index 5c184f8..9f8eb40 100644 --- a/clang-tools-extra/clang-tidy/misc/MisleadingIdentifier.h +++ b/clang-tools-extra/clang-tidy/misc/MisleadingIdentifierCheck.h @@ -6,13 +6,19 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGIDENTIFIER_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGIDENTIFIER_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGIDENTIFIERCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGIDENTIFIERCHECK_H #include "../ClangTidyCheck.h" namespace clang::tidy::misc { +/// Finds identifiers that contain Unicode characters with right-to-left +/// direction, which can be confusing as they may change the understanding of a +/// whole statement line. +/// +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/misc/misleading-identifier.html class MisleadingIdentifierCheck : public ClangTidyCheck { public: MisleadingIdentifierCheck(StringRef Name, ClangTidyContext *Context); @@ -24,4 +30,4 @@ public: } // namespace clang::tidy::misc -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGIDENTIFIER_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MISLEADINGIDENTIFIERCHECK_H diff --git a/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.cpp b/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.cpp index a44e9b3..0471ba8 100644 --- a/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/NewDeleteOverloadsCheck.cpp @@ -114,17 +114,15 @@ hasCorrespondingOverloadInBaseClass(const CXXMethodDecl *MD, RD = MD->getParent(); } - for (const auto &BS : RD->bases()) { + return llvm::any_of(RD->bases(), [&](const CXXBaseSpecifier &BS) { // We can't say much about a dependent base class, but to avoid false // positives assume it can have a corresponding overload. if (BS.getType()->isDependentType()) return true; - if (const auto *BaseRD = BS.getType()->getAsCXXRecordDecl()) - if (hasCorrespondingOverloadInBaseClass(MD, BaseRD)) - return true; - } - - return false; + if (const CXXRecordDecl *BaseRD = BS.getType()->getAsCXXRecordDecl()) + return hasCorrespondingOverloadInBaseClass(MD, BaseRD); + return false; + }); } void NewDeleteOverloadsCheck::registerMatchers(MatchFinder *Finder) { diff --git a/clang-tools-extra/clang-tidy/misc/NonCopyableObjects.cpp b/clang-tools-extra/clang-tidy/misc/NonCopyableObjectsCheck.cpp index b33e266..bfeb5fa 100644 --- a/clang-tools-extra/clang-tidy/misc/NonCopyableObjects.cpp +++ b/clang-tools-extra/clang-tidy/misc/NonCopyableObjectsCheck.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "NonCopyableObjects.h" +#include "NonCopyableObjectsCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" diff --git a/clang-tools-extra/clang-tidy/misc/NonCopyableObjects.h b/clang-tools-extra/clang-tidy/misc/NonCopyableObjectsCheck.h index 2fcbf41..608e078 100644 --- a/clang-tools-extra/clang-tidy/misc/NonCopyableObjects.h +++ b/clang-tools-extra/clang-tidy/misc/NonCopyableObjectsCheck.h @@ -6,15 +6,18 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONCOPYABLEOBJECTS_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONCOPYABLEOBJECTS_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONCOPYABLEOBJECTSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONCOPYABLEOBJECTSCHECK_H #include "../ClangTidyCheck.h" namespace clang::tidy::misc { -/// The check flags dereferences and non-pointer declarations of objects that +/// Flags dereferences and non-pointer declarations of objects that /// are not meant to be passed by value, such as C FILE objects. +/// +/// For the user-facing documentation see: +/// https://clang.llvm.org/extra/clang-tidy/checks/misc/non-copyable-objects.html class NonCopyableObjectsCheck : public ClangTidyCheck { public: NonCopyableObjectsCheck(StringRef Name, ClangTidyContext *Context) @@ -25,4 +28,4 @@ public: } // namespace clang::tidy::misc -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONCOPYABLEOBJECTS_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONCOPYABLEOBJECTSCHECK_H diff --git a/clang-tools-extra/clang-tidy/cert/LimitedRandomnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/PredictableRandCheck.cpp index 4fe9c6c..eed80e0 100644 --- a/clang-tools-extra/clang-tidy/cert/LimitedRandomnessCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/PredictableRandCheck.cpp @@ -6,22 +6,22 @@ // //===----------------------------------------------------------------------===// -#include "LimitedRandomnessCheck.h" +#include "PredictableRandCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" using namespace clang::ast_matchers; -namespace clang::tidy::cert { +namespace clang::tidy::misc { -void LimitedRandomnessCheck::registerMatchers(MatchFinder *Finder) { +void PredictableRandCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(callExpr(callee(functionDecl(namedDecl(hasName("::rand")), parameterCountIs(0)))) .bind("randomGenerator"), this); } -void LimitedRandomnessCheck::check(const MatchFinder::MatchResult &Result) { +void PredictableRandCheck::check(const MatchFinder::MatchResult &Result) { std::string Msg; if (getLangOpts().CPlusPlus) Msg = "; use C++11 random library instead"; @@ -30,4 +30,4 @@ void LimitedRandomnessCheck::check(const MatchFinder::MatchResult &Result) { diag(MatchedDecl->getBeginLoc(), "rand() has limited randomness" + Msg); } -} // namespace clang::tidy::cert +} // namespace clang::tidy::misc diff --git a/clang-tools-extra/clang-tidy/cert/LimitedRandomnessCheck.h b/clang-tools-extra/clang-tidy/misc/PredictableRandCheck.h index a806cd3..2237e7e 100644 --- a/clang-tools-extra/clang-tidy/cert/LimitedRandomnessCheck.h +++ b/clang-tools-extra/clang-tidy/misc/PredictableRandCheck.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_LIMITEDRANDOMNESSCHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_LIMITEDRANDOMNESSCHECK_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_PREDICTABLERANDCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_PREDICTABLERANDCHECK_H #include "../ClangTidyCheck.h" -namespace clang::tidy::cert { +namespace clang::tidy::misc { /// Pseudorandom number generators are not genuinely random. The result of the /// std::rand() function makes no guarantees as to the quality of the random @@ -19,15 +19,15 @@ namespace clang::tidy::cert { /// This check warns for the usage of std::rand() function. /// /// For the user-facing documentation see: -/// https://clang.llvm.org/extra/clang-tidy/checks/cert/msc50-cpp.html -class LimitedRandomnessCheck : public ClangTidyCheck { +/// https://clang.llvm.org/extra/clang-tidy/checks/misc/predictable-rand.html +class PredictableRandCheck : public ClangTidyCheck { public: - LimitedRandomnessCheck(StringRef Name, ClangTidyContext *Context) + PredictableRandCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; }; -} // namespace clang::tidy::cert +} // namespace clang::tidy::misc -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CERT_LIMITEDRANDOMNESSCHECK_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_PREDICTABLERANDCHECK_H diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp index c8ae41c..2b63dab 100644 --- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp @@ -890,7 +890,6 @@ static bool areStringsSameIgnoreSpaces(const llvm::StringRef Left, static bool areExprsSameMacroOrLiteral(const BinaryOperator *BinOp, const ASTContext *Context) { - if (!BinOp) return false; @@ -1147,16 +1146,18 @@ void RedundantExpressionCheck::checkArithmeticExpr( } } -static bool exprEvaluatesToZero(BinaryOperatorKind Opcode, APSInt Value) { +static bool exprEvaluatesToZero(BinaryOperatorKind Opcode, + const APSInt &Value) { return (Opcode == BO_And || Opcode == BO_AndAssign) && Value == 0; } static bool exprEvaluatesToBitwiseNegatedZero(BinaryOperatorKind Opcode, - APSInt Value) { + const APSInt &Value) { return (Opcode == BO_Or || Opcode == BO_OrAssign) && ~Value == 0; } -static bool exprEvaluatesToSymbolic(BinaryOperatorKind Opcode, APSInt Value) { +static bool exprEvaluatesToSymbolic(BinaryOperatorKind Opcode, + const APSInt &Value) { return ((Opcode == BO_Or || Opcode == BO_OrAssign) && Value == 0) || ((Opcode == BO_And || Opcode == BO_AndAssign) && ~Value == 0); } diff --git a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp index ae08096..9c38bb1 100644 --- a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp @@ -30,13 +30,10 @@ static bool isOverrideMethod(const FunctionDecl *Function) { static bool hasAttrAfterParam(const SourceManager *SourceManager, const ParmVarDecl *Param) { - for (const auto *Attr : Param->attrs()) { - if (SourceManager->isBeforeInTranslationUnit(Param->getLocation(), - Attr->getLocation())) { - return true; - } - } - return false; + return llvm::any_of(Param->attrs(), [&](const Attr *Attr) { + return SourceManager->isBeforeInTranslationUnit(Param->getLocation(), + Attr->getLocation()); + }); } void UnusedParametersCheck::registerMatchers(MatchFinder *Finder) { @@ -160,7 +157,6 @@ void UnusedParametersCheck::warnOnUnusedParameter( !Result.SourceManager->isInMainFile(Function->getLocation()) || !Indexer->getOtherRefs(Function).empty() || isOverrideMethod(Function) || isLambdaCallOperator(Function)) { - // It is illegal to omit parameter name here in C code, so early-out. if (!Result.Context->getLangOpts().CPlusPlus) return; diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp index 1c0043b..7663f37 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidBindCheck.cpp @@ -252,14 +252,13 @@ static SmallVector<BindArgument, 4> buildBindArguments(const MatchFinder::MatchResult &Result, const CallableInfo &Callable) { SmallVector<BindArgument, 4> BindArguments; - static llvm::Regex MatchPlaceholder("^_([0-9]+)$"); + static const llvm::Regex MatchPlaceholder("^_([0-9]+)$"); const auto *BindCall = Result.Nodes.getNodeAs<CallExpr>("bind"); // Start at index 1 as first argument to bind is the function name. unsigned CaptureIndex = 0; for (size_t I = 1, ArgCount = BindCall->getNumArgs(); I < ArgCount; ++I) { - const Expr *E = BindCall->getArg(I); BindArgument &B = BindArguments.emplace_back(); @@ -267,7 +266,7 @@ buildBindArguments(const MatchFinder::MatchResult &Result, if (Callable.Type == CT_MemberFunction) --ArgIndex; - bool IsObjectPtr = (I == 1 && Callable.Type == CT_MemberFunction); + const bool IsObjectPtr = (I == 1 && Callable.Type == CT_MemberFunction); B.E = E; B.SourceTokens = getSourceTextForExpr(Result, E); @@ -327,7 +326,6 @@ static int findPositionOfPlaceholderUse(ArrayRef<BindArgument> Args, static void addPlaceholderArgs(const LambdaProperties &LP, llvm::raw_ostream &Stream, bool PermissiveParameterList) { - ArrayRef<BindArgument> Args = LP.BindArguments; const auto *MaxPlaceholderIt = llvm::max_element( @@ -340,13 +338,13 @@ static void addPlaceholderArgs(const LambdaProperties &LP, MaxPlaceholderIt->PlaceHolderIndex == 0)) return; - size_t PlaceholderCount = MaxPlaceholderIt->PlaceHolderIndex; + const size_t PlaceholderCount = MaxPlaceholderIt->PlaceHolderIndex; Stream << "("; StringRef Delimiter = ""; for (size_t I = 1; I <= PlaceholderCount; ++I) { Stream << Delimiter << "auto &&"; - int ArgIndex = findPositionOfPlaceholderUse(Args, I); + const int ArgIndex = findPositionOfPlaceholderUse(Args, I); if (ArgIndex != -1 && Args[ArgIndex].IsUsed) Stream << " " << Args[ArgIndex].UsageIdentifier; @@ -392,7 +390,7 @@ findCandidateCallOperators(const CXXRecordDecl *RecordDecl, size_t NumArgs) { std::vector<const FunctionDecl *> Candidates; for (const clang::CXXMethodDecl *Method : RecordDecl->methods()) { - OverloadedOperatorKind OOK = Method->getOverloadedOperator(); + const OverloadedOperatorKind OOK = Method->getOverloadedOperator(); if (OOK != OverloadedOperatorKind::OO_Call) continue; @@ -410,7 +408,7 @@ findCandidateCallOperators(const CXXRecordDecl *RecordDecl, size_t NumArgs) { continue; const FunctionDecl *FD = FTD->getTemplatedDecl(); - OverloadedOperatorKind OOK = FD->getOverloadedOperator(); + const OverloadedOperatorKind OOK = FD->getOverloadedOperator(); if (OOK != OverloadedOperatorKind::OO_Call) continue; @@ -465,13 +463,12 @@ static const FunctionDecl *getCallOperator(const CXXRecordDecl *Callable, static const FunctionDecl * getCallMethodDecl(const MatchFinder::MatchResult &Result, CallableType Type, CallableMaterializationKind Materialization) { - const Expr *Callee = Result.Nodes.getNodeAs<Expr>("ref"); const Expr *CallExpression = ignoreTemporariesAndPointers(Callee); if (Type == CT_Object) { const auto *BindCall = Result.Nodes.getNodeAs<CallExpr>("bind"); - size_t NumArgs = BindCall->getNumArgs() - 1; + const size_t NumArgs = BindCall->getNumArgs() - 1; return getCallOperator(Callee->getType()->getAsCXXRecordDecl(), NumArgs); } @@ -488,7 +485,7 @@ getCallMethodDecl(const MatchFinder::MatchResult &Result, CallableType Type, static CallableType getCallableType(const MatchFinder::MatchResult &Result) { const auto *CallableExpr = Result.Nodes.getNodeAs<Expr>("ref"); - QualType QT = CallableExpr->getType(); + const QualType QT = CallableExpr->getType(); if (QT->isMemberFunctionPointerType()) return CT_MemberFunction; @@ -614,7 +611,7 @@ static void emitCaptureList(const LambdaProperties &LP, if (B.CM == CM_None || !B.IsUsed) continue; - StringRef Delimiter = AnyCapturesEmitted ? ", " : ""; + const StringRef Delimiter = AnyCapturesEmitted ? ", " : ""; if (emitCapture(CaptureSet, Delimiter, B.CM, B.CE, B.CaptureIdentifier, B.SourceTokens, Stream)) @@ -669,7 +666,7 @@ void AvoidBindCheck::check(const MatchFinder::MatchResult &Result) { emitCaptureList(LP, Result, Stream); Stream << "]"; - ArrayRef<BindArgument> FunctionCallArgs = ArrayRef(LP.BindArguments); + const ArrayRef<BindArgument> FunctionCallArgs = ArrayRef(LP.BindArguments); addPlaceholderArgs(LP, Stream, PermissiveParameterList); diff --git a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCStyleCastCheck.cpp index 3a5a9cd..7f9bf63 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidCStyleCastCheck.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "AvoidCStyleCastsCheck.h" +#include "AvoidCStyleCastCheck.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -14,10 +14,9 @@ using namespace clang::ast_matchers; -namespace clang::tidy::google::readability { +namespace clang::tidy::modernize { -void AvoidCStyleCastsCheck::registerMatchers( - ast_matchers::MatchFinder *Finder) { +void AvoidCStyleCastCheck::registerMatchers(ast_matchers::MatchFinder *Finder) { Finder->addMatcher( cStyleCastExpr( // Filter out (EnumType)IntegerLiteral construct, which is generated @@ -113,7 +112,7 @@ static bool sameTypeAsWritten(QualType X, QualType Y) { } } -void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) { +void AvoidCStyleCastCheck::check(const MatchFinder::MatchResult &Result) { const auto *CastExpr = Result.Nodes.getNodeAs<ExplicitCastExpr>("cast"); // Ignore casts in macros. @@ -248,6 +247,12 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) { } break; } + if (DestType->isVoidPointerType() && SourceType->isPointerType() && + !SourceType->getPointeeType()->isPointerType()) { + ReplaceWithNamedCast("reinterpret_cast"); + return; + } + [[fallthrough]]; case clang::CK_IntegralCast: // Convert integral and no-op casts between builtin types and enums to @@ -269,6 +274,12 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) { return; } break; + case CK_BaseToDerived: + if (!needsConstCast(SourceType, DestType)) { + ReplaceWithNamedCast("static_cast"); + return; + } + break; default: break; } @@ -276,4 +287,4 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) { Diag << "static_cast/const_cast/reinterpret_cast"; } -} // namespace clang::tidy::google::readability +} // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.h b/clang-tools-extra/clang-tidy/modernize/AvoidCStyleCastCheck.h index a305bd5..123d524 100644 --- a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/AvoidCStyleCastCheck.h @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDCSTYLECASTSCHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDCSTYLECASTSCHECK_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDCSTYLECASTCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDCSTYLECASTCHECK_H #include "../ClangTidyCheck.h" -namespace clang::tidy::google::readability { +namespace clang::tidy::modernize { /// Finds usages of C-style casts. /// @@ -24,10 +24,10 @@ namespace clang::tidy::google::readability { /// ones generated by `-Wold-style-cast`. /// /// For the user-facing documentation see: -/// https://clang.llvm.org/extra/clang-tidy/checks/google/readability-casting.html -class AvoidCStyleCastsCheck : public ClangTidyCheck { +/// https://clang.llvm.org/extra/clang-tidy/checks/modernize/avoid-c-style-cast.html +class AvoidCStyleCastCheck : public ClangTidyCheck { public: - AvoidCStyleCastsCheck(StringRef Name, ClangTidyContext *Context) + AvoidCStyleCastCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; @@ -36,6 +36,6 @@ public: } }; -} // namespace clang::tidy::google::readability +} // namespace clang::tidy::modernize -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDCSTYLECASTSCHECK_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_AVOIDCSTYLECASTCHECK_H diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 882f2dc..488c359 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -6,6 +6,7 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangTidyModernizeModule STATIC AvoidBindCheck.cpp AvoidCArraysCheck.cpp + AvoidCStyleCastCheck.cpp AvoidSetjmpLongjmpCheck.cpp AvoidVariadicFunctionsCheck.cpp ConcatNestedNamespacesCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp index 6e28cb2..7c82e9e 100644 --- a/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp @@ -25,7 +25,8 @@ static bool locationsInSameFile(const SourceManager &Sources, static StringRef getRawStringRef(const SourceRange &Range, const SourceManager &Sources, const LangOptions &LangOpts) { - CharSourceRange TextRange = Lexer::getAsCharRange(Range, Sources, LangOpts); + const CharSourceRange TextRange = + Lexer::getAsCharRange(Range, Sources, LangOpts); return Lexer::getSourceText(TextRange, Sources, LangOpts); } @@ -56,15 +57,16 @@ SourceRange NS::getDefaultNamespaceBackRange() const { SourceRange NS::getNamespaceBackRange(const SourceManager &SM, const LangOptions &LangOpts) const { // Back from '}' to conditional '// namespace xxx' - SourceLocation Loc = front()->getRBraceLoc(); + const SourceLocation Loc = front()->getRBraceLoc(); std::optional<Token> Tok = utils::lexer::findNextTokenIncludingComments(Loc, SM, LangOpts); if (!Tok) return getDefaultNamespaceBackRange(); if (Tok->getKind() != tok::TokenKind::comment) return getDefaultNamespaceBackRange(); - SourceRange TokRange = SourceRange{Tok->getLocation(), Tok->getEndLoc()}; - StringRef TokText = getRawStringRef(TokRange, SM, LangOpts); + const SourceRange TokRange = + SourceRange{Tok->getLocation(), Tok->getEndLoc()}; + const StringRef TokText = getRawStringRef(TokRange, SM, LangOpts); NamespaceName CloseComment{"namespace "}; appendCloseComment(CloseComment); // current fix hint in readability/NamespaceCommentCheck.cpp use single line @@ -98,7 +100,7 @@ bool ConcatNestedNamespacesCheck::unsupportedNamespace(const NamespaceDecl &ND, return true; if (getLangOpts().CPlusPlus20) { // C++20 support inline nested namespace - bool IsFirstNS = IsChild || !Namespaces.empty(); + const bool IsFirstNS = IsChild || !Namespaces.empty(); return ND.isInlineNamespace() && !IsFirstNS; } return ND.isInlineNamespace(); @@ -106,7 +108,7 @@ bool ConcatNestedNamespacesCheck::unsupportedNamespace(const NamespaceDecl &ND, bool ConcatNestedNamespacesCheck::singleNamedNamespaceChild( const NamespaceDecl &ND) const { - NamespaceDecl::decl_range Decls = ND.decls(); + const NamespaceDecl::decl_range Decls = ND.decls(); if (std::distance(Decls.begin(), Decls.end()) != 1) return false; @@ -121,7 +123,7 @@ void ConcatNestedNamespacesCheck::registerMatchers( void ConcatNestedNamespacesCheck::reportDiagnostic( const SourceManager &SM, const LangOptions &LangOpts) { - DiagnosticBuilder DB = + const DiagnosticBuilder DB = diag(Namespaces.front().front()->getBeginLoc(), "nested namespaces can be concatenated", DiagnosticIDs::Warning); @@ -143,7 +145,7 @@ void ConcatNestedNamespacesCheck::reportDiagnostic( // the last one should be handled specially Fronts.pop_back(); - SourceRange LastRBrace = Backs.pop_back_val(); + const SourceRange LastRBrace = Backs.pop_back_val(); NamespaceName ConcatNameSpace{"namespace "}; for (const NS &NS : Namespaces) { diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp index 1de9e13..eff7c2f 100644 --- a/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedHeadersCheck.cpp @@ -135,7 +135,6 @@ IncludeModernizePPCallbacks::IncludeModernizePPCallbacks( const LangOptions &LangOpts, const SourceManager &SM, bool CheckHeaderFile) : IncludesToBeProcessed(IncludesToBeProcessed), SM(SM), CheckHeaderFile(CheckHeaderFile) { - static constexpr std::pair<StringRef, StringRef> CXX98Headers[] = { {"assert.h", "cassert"}, {"complex.h", "complex"}, {"ctype.h", "cctype"}, {"errno.h", "cerrno"}, @@ -167,7 +166,6 @@ void IncludeModernizePPCallbacks::InclusionDirective( bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule, bool ModuleImported, SrcMgr::CharacteristicKind FileType) { - // If we don't want to warn for non-main file reports and this is one, skip // it. if (!CheckHeaderFile && !SM.isInMainFile(HashLoc)) @@ -184,7 +182,7 @@ void IncludeModernizePPCallbacks::InclusionDirective( // 1. Insert std prefix for every such symbol occurrence. // 2. Insert `using namespace std;` to the beginning of TU. // 3. Do nothing and let the user deal with the migration himself. - SourceLocation DiagLoc = FilenameRange.getBegin(); + const SourceLocation DiagLoc = FilenameRange.getBegin(); if (auto It = CStyledHeaderToCxx.find(FileName); It != CStyledHeaderToCxx.end()) { IncludesToBeProcessed.emplace_back(IncludeMarker{ diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp index 5e25437..7e43165 100644 --- a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp @@ -36,10 +36,10 @@ void DeprecatedIosBaseAliasesCheck::registerMatchers(MatchFinder *Finder) { void DeprecatedIosBaseAliasesCheck::check( const MatchFinder::MatchResult &Result) { - SourceManager &SM = *Result.SourceManager; + const SourceManager &SM = *Result.SourceManager; const auto *Typedef = Result.Nodes.getNodeAs<TypedefDecl>("TypeDecl"); - StringRef TypeName = Typedef->getName(); + const StringRef TypeName = Typedef->getName(); auto Replacement = getReplacementType(TypeName); TypeLoc TL = *Result.Nodes.getNodeAs<TypeLoc>("TypeLoc"); @@ -55,7 +55,8 @@ void DeprecatedIosBaseAliasesCheck::check( Fix = false; } - SourceLocation EndLoc = IoStateLoc.getLocWithOffset(TypeName.size() - 1); + const SourceLocation EndLoc = + IoStateLoc.getLocWithOffset(TypeName.size() - 1); if (Replacement) { const char *FixName = *Replacement; diff --git a/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.cpp b/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.cpp index 05cf51a..862ca18 100644 --- a/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.cpp +++ b/clang-tools-extra/clang-tidy/modernize/IntegralLiteralExpressionMatcher.cpp @@ -95,7 +95,7 @@ bool IntegralLiteralExpressionMatcher::unaryOperator() { } static LiteralSize literalTokenSize(const Token &Tok) { - unsigned int Length = Tok.getLength(); + const unsigned int Length = Tok.getLength(); if (Length <= 1) return LiteralSize::Int; diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp index fea5ac6..19b406f 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -92,7 +92,7 @@ static StatementMatcher incrementVarMatcher() { } static StatementMatcher -arrayConditionMatcher(internal::Matcher<Expr> LimitExpr) { +arrayConditionMatcher(const internal::Matcher<Expr> &LimitExpr) { return binaryOperator( anyOf(allOf(hasOperatorName("<"), hasLHS(integerComparisonMatcher()), hasRHS(LimitExpr)), @@ -115,7 +115,7 @@ arrayConditionMatcher(internal::Matcher<Expr> LimitExpr) { /// - The index variable is only used as an array index. /// - All arrays indexed by the loop are the same. static StatementMatcher makeArrayLoopMatcher() { - StatementMatcher ArrayBoundMatcher = + const StatementMatcher ArrayBoundMatcher = expr(hasType(isInteger())).bind(ConditionBoundName); return forStmt(unless(isInTemplateInstantiation()), @@ -156,7 +156,6 @@ static StatementMatcher makeArrayLoopMatcher() { /// Client code will need to make sure that: /// - The two containers on which 'begin' and 'end' are called are the same. static StatementMatcher makeIteratorLoopMatcher(bool IsReverse) { - auto BeginNameMatcher = IsReverse ? hasAnyName("rbegin", "crbegin") : hasAnyName("begin", "cbegin"); auto BeginNameMatcherStd = IsReverse @@ -168,7 +167,7 @@ static StatementMatcher makeIteratorLoopMatcher(bool IsReverse) { auto EndNameMatcherStd = IsReverse ? hasAnyName("::std::rend", "::std::crend") : hasAnyName("::std::end", "::std::cend"); - StatementMatcher BeginCallMatcher = + const StatementMatcher BeginCallMatcher = expr(anyOf(cxxMemberCallExpr(argumentCountIs(0), callee(cxxMethodDecl(BeginNameMatcher))), callExpr(argumentCountIs(1), @@ -177,37 +176,37 @@ static StatementMatcher makeIteratorLoopMatcher(bool IsReverse) { callee(functionDecl(BeginNameMatcherStd))))) .bind(BeginCallName); - DeclarationMatcher InitDeclMatcher = + const DeclarationMatcher InitDeclMatcher = varDecl(hasInitializer(anyOf(ignoringParenImpCasts(BeginCallMatcher), materializeTemporaryExpr( ignoringParenImpCasts(BeginCallMatcher)), hasDescendant(BeginCallMatcher)))) .bind(InitVarName); - DeclarationMatcher EndDeclMatcher = + const DeclarationMatcher EndDeclMatcher = varDecl(hasInitializer(anything())).bind(EndVarName); - StatementMatcher EndCallMatcher = expr(anyOf( + const StatementMatcher EndCallMatcher = expr(anyOf( cxxMemberCallExpr(argumentCountIs(0), callee(cxxMethodDecl(EndNameMatcher))), callExpr(argumentCountIs(1), callee(functionDecl(EndNameMatcher)), usesADL()), callExpr(argumentCountIs(1), callee(functionDecl(EndNameMatcherStd))))); - StatementMatcher IteratorBoundMatcher = + const StatementMatcher IteratorBoundMatcher = expr(anyOf(ignoringParenImpCasts( declRefExpr(to(varDecl(equalsBoundNode(EndVarName))))), ignoringParenImpCasts(expr(EndCallMatcher).bind(EndCallName)), materializeTemporaryExpr(ignoringParenImpCasts( expr(EndCallMatcher).bind(EndCallName))))); - StatementMatcher IteratorComparisonMatcher = expr(ignoringParenImpCasts( + const StatementMatcher IteratorComparisonMatcher = expr(ignoringParenImpCasts( declRefExpr(to(varDecl(equalsBoundNode(InitVarName)))))); // This matcher tests that a declaration is a CXXRecordDecl that has an // overloaded operator*(). If the operator*() returns by value instead of by // reference then the return type is tagged with DerefByValueResultName. - internal::Matcher<VarDecl> TestDerefReturnsByValue = + const internal::Matcher<VarDecl> TestDerefReturnsByValue = hasType(hasUnqualifiedDesugaredType( recordType(hasDeclaration(cxxRecordDecl(hasMethod(cxxMethodDecl( hasOverloadedOperatorName("*"), @@ -280,7 +279,7 @@ static StatementMatcher makePseudoArrayLoopMatcher() { // FIXME: Also, a record doesn't necessarily need begin() and end(). Free // functions called begin() and end() taking the container as an argument // are also allowed. - TypeMatcher RecordWithBeginEnd = qualType(anyOf( + const TypeMatcher RecordWithBeginEnd = qualType(anyOf( qualType(isConstQualified(), hasUnqualifiedDesugaredType(recordType(hasDeclaration( cxxRecordDecl(isSameOrDerivedFrom(cxxRecordDecl( @@ -295,7 +294,7 @@ static StatementMatcher makePseudoArrayLoopMatcher() { hasMethod(hasName("end"))))))))) // qualType )); - StatementMatcher SizeCallMatcher = expr(anyOf( + const StatementMatcher SizeCallMatcher = expr(anyOf( cxxMemberCallExpr(argumentCountIs(0), callee(cxxMethodDecl(hasAnyName("size", "length"))), on(anyOf(hasType(pointsTo(RecordWithBeginEnd)), @@ -310,10 +309,10 @@ static StatementMatcher makePseudoArrayLoopMatcher() { explicitCastExpr(hasSourceExpression(ignoringParenImpCasts( expr(SizeCallMatcher).bind(EndCallName)))))); - DeclarationMatcher EndDeclMatcher = + const DeclarationMatcher EndDeclMatcher = varDecl(hasInitializer(EndInitMatcher)).bind(EndVarName); - StatementMatcher IndexBoundMatcher = + const StatementMatcher IndexBoundMatcher = expr(anyOf(ignoringParenImpCasts( declRefExpr(to(varDecl(equalsBoundNode(EndVarName))))), EndInitMatcher)); @@ -511,27 +510,24 @@ static bool canBeModified(ASTContext *Context, const Expr *E) { /// Returns true when it can be guaranteed that the elements of the /// container are not being modified. static bool usagesAreConst(ASTContext *Context, const UsageResult &Usages) { - for (const Usage &U : Usages) { + return llvm::none_of(Usages, [&Context](const Usage &U) { // Lambda captures are just redeclarations (VarDecl) of the same variable, // not expressions. If we want to know if a variable that is captured by // reference can be modified in an usage inside the lambda's body, we need // to find the expression corresponding to that particular usage, later in // this loop. - if (U.Kind != Usage::UK_CaptureByCopy && U.Kind != Usage::UK_CaptureByRef && - canBeModified(Context, U.Expression)) - return false; - } - return true; + return U.Kind != Usage::UK_CaptureByCopy && + U.Kind != Usage::UK_CaptureByRef && + canBeModified(Context, U.Expression); + }); } /// Returns true if the elements of the container are never accessed /// by reference. static bool usagesReturnRValues(const UsageResult &Usages) { - for (const auto &U : Usages) { - if (U.Expression && !U.Expression->isPRValue()) - return false; - } - return true; + return llvm::all_of(Usages, [](const Usage &U) { + return !U.Expression || U.Expression->isPRValue(); + }); } /// Returns true if the container is const-qualified. @@ -563,7 +559,6 @@ LoopConvertCheck::LoopConvertCheck(StringRef Name, ClangTidyContext *Context) UseCxx20IfAvailable(Options.get("UseCxx20ReverseRanges", true)), ReverseFunction(Options.get("MakeReverseRangeFunction", "")), ReverseHeader(Options.get("MakeReverseRangeHeader", "")) { - if (ReverseFunction.empty() && !ReverseHeader.empty()) { configurationDiag( "modernize-loop-convert: 'MakeReverseRangeHeader' is set but " @@ -620,7 +615,7 @@ void LoopConvertCheck::getAliasRange(SourceManager &SM, SourceRange &Range) { SM.getCharacterData(Range.getEnd().getLocWithOffset(1), &Invalid); if (Invalid) return; - unsigned Offset = std::strspn(TextAfter, " \t\r\n"); + const unsigned Offset = std::strspn(TextAfter, " \t\r\n"); Range = SourceRange(Range.getBegin(), Range.getEnd().getLocWithOffset(Offset)); } @@ -633,7 +628,7 @@ void LoopConvertCheck::doConversion( const DeclStmt *AliasDecl, bool AliasUseRequired, bool AliasFromForInit, const ForStmt *Loop, RangeDescriptor Descriptor) { std::string VarNameOrStructuredBinding; - bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl; + const bool VarNameFromAlias = (Usages.size() == 1) && AliasDecl; bool AliasVarIsRef = false; bool CanCopy = true; std::vector<FixItHint> FixIts; @@ -743,7 +738,7 @@ void LoopConvertCheck::doConversion( } // Now, we need to construct the new range expression. - SourceRange ParenRange(Loop->getLParenLoc(), Loop->getRParenLoc()); + const SourceRange ParenRange(Loop->getLParenLoc(), Loop->getRParenLoc()); QualType Type = Context->getAutoDeductType(); if (!Descriptor.ElemType.isNull() && Descriptor.ElemType->isFundamentalType()) @@ -753,14 +748,15 @@ void LoopConvertCheck::doConversion( // If the new variable name is from the aliased variable, then the reference // type for the new variable should only be used if the aliased variable was // declared as a reference. - bool IsCheapToCopy = + const bool IsCheapToCopy = !Descriptor.ElemType.isNull() && Descriptor.ElemType.isTriviallyCopyableType(*Context) && !Descriptor.ElemType->isDependentSizedArrayType() && // TypeInfo::Width is in bits. Context->getTypeInfo(Descriptor.ElemType).Width <= 8 * MaxCopySize; - bool UseCopy = CanCopy && ((VarNameFromAlias && !AliasVarIsRef) || - (Descriptor.DerefByConstRef && IsCheapToCopy)); + const bool UseCopy = + CanCopy && ((VarNameFromAlias && !AliasVarIsRef) || + (Descriptor.DerefByConstRef && IsCheapToCopy)); if (!UseCopy) { if (Descriptor.DerefByConstRef) { @@ -866,7 +862,7 @@ void LoopConvertCheck::getIteratorLoopQualifiers(ASTContext *Context, // The matchers for iterator loops provide bound nodes to obtain this // information. const auto *InitVar = Nodes.getNodeAs<VarDecl>(InitVarName); - QualType CanonicalInitVarType = InitVar->getType().getCanonicalType(); + const QualType CanonicalInitVarType = InitVar->getType().getCanonicalType(); const auto *DerefByValueType = Nodes.getNodeAs<QualType>(DerefByValueResultName); Descriptor.DerefByValue = DerefByValueType; @@ -934,12 +930,12 @@ bool LoopConvertCheck::isConvertible(ASTContext *Context, // FIXME: Try to put most of this logic inside a matcher. if (FixerKind == LFK_Iterator || FixerKind == LFK_ReverseIterator) { - QualType InitVarType = InitVar->getType(); - QualType CanonicalInitVarType = InitVarType.getCanonicalType(); + const QualType InitVarType = InitVar->getType(); + const QualType CanonicalInitVarType = InitVarType.getCanonicalType(); const auto *BeginCall = Nodes.getNodeAs<CallExpr>(BeginCallName); assert(BeginCall && "Bad Callback. No begin call expression"); - QualType CanonicalBeginType = + const QualType CanonicalBeginType = BeginCall->getDirectCallee()->getReturnType().getCanonicalType(); if (CanonicalBeginType->isPointerType() && CanonicalInitVarType->isPointerType()) { @@ -1054,7 +1050,7 @@ void LoopConvertCheck::check(const MatchFinder::MatchResult &Result) { } // Find out which qualifiers we have to use in the loop range. - TraversalKindScope RAII(*Context, TK_AsIs); + const TraversalKindScope RAII(*Context, TK_AsIs); const UsageResult &Usages = Finder.getUsages(); determineRangeDescriptor(Context, Nodes, Loop, FixerKind, ContainerExpr, Usages, Descriptor); diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp index 6fb7808..f6685dd 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp @@ -89,19 +89,18 @@ bool DependencyFinderASTVisitor::VisitVarDecl(VarDecl *V) { // Next, check if the variable was removed from existence by an earlier // iteration. - for (const auto &I : *ReplacedVars) { - if (I.second == V) { - DependsOnInsideVariable = true; - return false; - } - } - return true; + if (llvm::none_of(*ReplacedVars, + [&](const auto &I) { return I.second == V; })) + return true; + DependsOnInsideVariable = true; + return false; } /// If we already created a variable for TheLoop, check to make sure /// that the name was not already taken. bool DeclFinderASTVisitor::VisitForStmt(ForStmt *TheLoop) { - StmtGeneratedVarNameMap::const_iterator I = GeneratedDecls->find(TheLoop); + const StmtGeneratedVarNameMap::const_iterator I = + GeneratedDecls->find(TheLoop); if (I != GeneratedDecls->end() && I->second == Name) { Found = true; return false; @@ -131,7 +130,7 @@ bool DeclFinderASTVisitor::VisitDeclRefExpr(DeclRefExpr *DeclRef) { /// If the new variable name conflicts with any type used in the loop, /// then we mark that variable name as taken. bool DeclFinderASTVisitor::VisitTypeLoc(TypeLoc TL) { - QualType QType = TL.getType(); + const QualType QType = TL.getType(); // Check if our name conflicts with a type, to handle for typedefs. if (QType.getAsString() == Name) { @@ -233,11 +232,8 @@ static bool containsExpr(ASTContext *Context, const ContainerT *Container, const Expr *E) { llvm::FoldingSetNodeID ID; E->Profile(ID, *Context, true); - for (const auto &I : *Container) { - if (ID == I.second) - return true; - } - return false; + return llvm::any_of(*Container, + [&](const auto &I) { return ID == I.second; }); } /// Returns true when the index expression is a declaration reference to @@ -364,7 +360,7 @@ static bool isAliasDecl(ASTContext *Context, const Decl *TheDecl, // Check that the declared type is the same as (or a reference to) the // container type. if (!OnlyCasts) { - QualType InitType = Init->getType(); + const QualType InitType = Init->getType(); QualType DeclarationType = VDecl->getType(); if (!DeclarationType.isNull() && DeclarationType->isReferenceType()) DeclarationType = DeclarationType.getNonReferenceType(); @@ -440,7 +436,7 @@ static bool arrayMatchesBoundExpr(ASTContext *Context, ConditionExpr->getIntegerConstantExpr(*Context); if (!ConditionSize) return false; - llvm::APSInt ArraySize(ConstType->getSize()); + const llvm::APSInt ArraySize(ConstType->getSize()); return llvm::APSInt::isSameValue(*ConditionSize, ArraySize); } @@ -571,7 +567,7 @@ bool ForLoopIndexUseVisitor::TraverseMemberExpr(MemberExpr *Member) { // FIXME: This works around not having the location of the arrow operator. // Consider adding OperatorLoc to MemberExpr? - SourceLocation ArrowLoc = Lexer::getLocForEndOfToken( + const SourceLocation ArrowLoc = Lexer::getLocForEndOfToken( Base->getExprLoc(), 0, Context->getSourceManager(), Context->getLangOpts()); // If something complicated is happening (i.e. the next token isn't an @@ -821,7 +817,7 @@ bool ForLoopIndexUseVisitor::traverseStmtImpl(Stmt *S) { const Stmt *OldNextParent = NextStmtParent; CurrStmtParent = NextStmtParent; NextStmtParent = S; - bool Result = VisitorBase::TraverseStmt(S); + const bool Result = VisitorBase::TraverseStmt(S); NextStmtParent = OldNextParent; return Result; } @@ -850,7 +846,7 @@ std::string VariableNamer::createIndexName() { if (TheContainer) ContainerName = TheContainer->getName(); - size_t Len = ContainerName.size(); + const size_t Len = ContainerName.size(); if (Len > 1 && ContainerName.ends_with(Style == NS_UpperCase ? "S" : "s")) { IteratorName = std::string(ContainerName.substr(0, Len - 1)); // E.g.: (auto thing : things) @@ -876,7 +872,7 @@ std::string VariableNamer::createIndexName() { /// converter in a loop nested within SourceStmt. bool VariableNamer::declarationExists(StringRef Symbol) { assert(Context != nullptr && "Expected an ASTContext"); - IdentifierInfo &Ident = Context->Idents.get(Symbol); + const IdentifierInfo &Ident = Context->Idents.get(Symbol); // Check if the symbol is not an identifier (ie. is a keyword or alias). if (!isAnyIdentifier(Ident.getTokenID())) @@ -888,7 +884,7 @@ bool VariableNamer::declarationExists(StringRef Symbol) { // Determine if the symbol was generated in a parent context. for (const Stmt *S = SourceStmt; S != nullptr; S = ReverseAST->lookup(S)) { - StmtGeneratedVarNameMap::const_iterator I = GeneratedDecls->find(S); + const StmtGeneratedVarNameMap::const_iterator I = GeneratedDecls->find(S); if (I != GeneratedDecls->end() && I->second == Symbol) return true; } diff --git a/clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp index 2669aa2..098d46c 100644 --- a/clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MacroToEnumCheck.cpp @@ -23,7 +23,7 @@ static bool hasOnlyComments(SourceLocation Loc, const LangOptions &Options, StringRef Text) { // Use a lexer to look for tokens; if we find something other than a single // hash, then there were intervening tokens between macro definitions. - std::string Buffer{Text}; + const std::string Buffer{Text}; Lexer Lex(Loc, Options, Buffer.c_str(), Buffer.c_str(), Buffer.c_str() + Buffer.size()); Token Tok; @@ -47,7 +47,7 @@ static bool hasOnlyComments(SourceLocation Loc, const LangOptions &Options, }; WhiteSpace State = WhiteSpace::Nothing; - for (char C : Text) { + for (const char C : Text) { switch (C) { case '\r': if (State == WhiteSpace::CR) @@ -227,17 +227,17 @@ bool MacroToEnumCallbacks::isConsecutiveMacro(const MacroDirective *MD) const { if (CurrentFile->LastMacroLocation.isInvalid()) return false; - SourceLocation Loc = MD->getLocation(); + const SourceLocation Loc = MD->getLocation(); if (CurrentFile->LastLine + 1 == SM.getSpellingLineNumber(Loc)) return true; - SourceLocation Define = + const SourceLocation Define = SM.translateLineCol(SM.getFileID(Loc), SM.getSpellingLineNumber(Loc), 1); - CharSourceRange BetweenMacros{ + const CharSourceRange BetweenMacros{ SourceRange{CurrentFile->LastMacroLocation, Define}, true}; - CharSourceRange CharRange = + const CharSourceRange CharRange = Lexer::makeFileCharRange(BetweenMacros, SM, LangOpts); - StringRef BetweenText = Lexer::getSourceText(CharRange, SM, LangOpts); + const StringRef BetweenText = Lexer::getSourceText(CharRange, SM, LangOpts); return hasOnlyComments(Define, LangOpts, BetweenText); } @@ -258,7 +258,7 @@ void MacroToEnumCallbacks::conditionStart(const SourceLocation &Loc) { } void MacroToEnumCallbacks::checkCondition(SourceRange Range) { - CharSourceRange CharRange = Lexer::makeFileCharRange( + const CharSourceRange CharRange = Lexer::makeFileCharRange( CharSourceRange::getTokenRange(Range), SM, LangOpts); std::string Text = Lexer::getSourceText(CharRange, SM, LangOpts).str(); Lexer Lex(CharRange.getBegin(), LangOpts, Text.data(), Text.data(), @@ -285,7 +285,7 @@ void MacroToEnumCallbacks::checkName(const Token &MacroNameTok) { } void MacroToEnumCallbacks::rememberExpressionName(const Token &Tok) { - std::string Id = getTokenName(Tok).str(); + const std::string Id = getTokenName(Tok).str(); auto Pos = llvm::lower_bound(ExpressionNames, Id); if (Pos == ExpressionNames.end() || *Pos != Id) { ExpressionNames.insert(Pos, Id); @@ -294,7 +294,7 @@ void MacroToEnumCallbacks::rememberExpressionName(const Token &Tok) { void MacroToEnumCallbacks::rememberExpressionTokens( ArrayRef<Token> MacroTokens) { - for (Token Tok : MacroTokens) { + for (const Token Tok : MacroTokens) { if (Tok.isAnyIdentifier()) rememberExpressionName(Tok); } @@ -318,8 +318,8 @@ void MacroToEnumCallbacks::FileChanged(SourceLocation Loc, bool MacroToEnumCallbacks::isInitializer(ArrayRef<Token> MacroTokens) { IntegralLiteralExpressionMatcher Matcher(MacroTokens, LangOpts.C99 == 0); - bool Matched = Matcher.match(); - bool IsC = !LangOpts.CPlusPlus; + const bool Matched = Matcher.match(); + const bool IsC = !LangOpts.CPlusPlus; if (IsC && (Matcher.largestLiteralSize() != LiteralSize::Int && Matcher.largestLiteralSize() != LiteralSize::UnsignedInt)) return false; @@ -344,7 +344,7 @@ void MacroToEnumCallbacks::MacroDefined(const Token &MacroNameTok, return; const MacroInfo *Info = MD->getMacroInfo(); - ArrayRef<Token> MacroTokens = Info->tokens(); + const ArrayRef<Token> MacroTokens = Info->tokens(); if (Info->isBuiltinMacro() || MacroTokens.empty()) return; if (Info->isFunctionLike()) { @@ -474,26 +474,26 @@ void MacroToEnumCallbacks::fixEnumMacro(const MacroList &MacroList) const { MacroList.front().Directive->getMacroInfo()->getDefinitionLoc(); Begin = SM.translateLineCol(SM.getFileID(Begin), SM.getSpellingLineNumber(Begin), 1); - DiagnosticBuilder Diagnostic = + const DiagnosticBuilder Diagnostic = Check->diag(Begin, "replace macro with enum") << FixItHint::CreateInsertion(Begin, "enum {\n"); for (size_t I = 0U; I < MacroList.size(); ++I) { const EnumMacro &Macro = MacroList[I]; - SourceLocation DefineEnd = + const SourceLocation DefineEnd = Macro.Directive->getMacroInfo()->getDefinitionLoc(); - SourceLocation DefineBegin = SM.translateLineCol( + const SourceLocation DefineBegin = SM.translateLineCol( SM.getFileID(DefineEnd), SM.getSpellingLineNumber(DefineEnd), 1); CharSourceRange DefineRange; DefineRange.setBegin(DefineBegin); DefineRange.setEnd(DefineEnd); Diagnostic << FixItHint::CreateRemoval(DefineRange); - SourceLocation NameEnd = Lexer::getLocForEndOfToken( + const SourceLocation NameEnd = Lexer::getLocForEndOfToken( Macro.Directive->getMacroInfo()->getDefinitionLoc(), 0, SM, LangOpts); Diagnostic << FixItHint::CreateInsertion(NameEnd, " ="); - SourceLocation ValueEnd = Lexer::getLocForEndOfToken( + const SourceLocation ValueEnd = Lexer::getLocForEndOfToken( Macro.Directive->getMacroInfo()->getDefinitionEndLoc(), 0, SM, LangOpts); if (I < MacroList.size() - 1) diff --git a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp index 9d01e27..39c5def 100644 --- a/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// +#include "MakeSmartPtrCheck.h" #include "../utils/TypeTraits.h" -#include "MakeSharedCheck.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" @@ -24,7 +24,7 @@ static constexpr char NewExpression[] = "newExpression"; static std::string getNewExprName(const CXXNewExpr *NewExpr, const SourceManager &SM, const LangOptions &Lang) { - StringRef WrittenName = Lexer::getSourceText( + const StringRef WrittenName = Lexer::getSourceText( CharSourceRange::getTokenRange( NewExpr->getAllocatedTypeSourceInfo()->getTypeLoc().getSourceRange()), SM, Lang); @@ -134,9 +134,9 @@ void MakeSmartPtrCheck::check(const MatchFinder::MatchResult &Result) { // // The fix of the check has side effect, it introduces value initialization // which maybe unexpected and cause performance regression. - bool Initializes = New->hasInitializer() || - !utils::type_traits::isTriviallyDefaultConstructible( - New->getAllocatedType(), *Result.Context); + const bool Initializes = New->hasInitializer() || + !utils::type_traits::isTriviallyDefaultConstructible( + New->getAllocatedType(), *Result.Context); if (!Initializes && IgnoreDefaultInitialization) return; if (Construct) @@ -150,15 +150,15 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM, ASTContext *Ctx, const VarDecl *DVar, const QualType *Type, const CXXNewExpr *New) { - SourceLocation ConstructCallStart = Construct->getExprLoc(); - bool InMacro = ConstructCallStart.isMacroID(); + const SourceLocation ConstructCallStart = Construct->getExprLoc(); + const bool InMacro = ConstructCallStart.isMacroID(); if (InMacro && IgnoreMacros) { return; } bool Invalid = false; - StringRef ExprStr = Lexer::getSourceText( + const StringRef ExprStr = Lexer::getSourceText( CharSourceRange::getCharRange( ConstructCallStart, Construct->getParenOrBraceRange().getBegin()), SM, getLangOpts(), &Invalid); @@ -178,7 +178,7 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM, ASTContext *Ctx, } // Find the location of the template's left angle. - size_t LAngle = ExprStr.find('<'); + const size_t LAngle = ExprStr.find('<'); SourceLocation ConstructCallEnd; if (LAngle == StringRef::npos) { // If the template argument is missing (because it is part of the alias) @@ -202,7 +202,7 @@ void MakeSmartPtrCheck::checkConstruct(SourceManager &SM, ASTContext *Ctx, // If the smart_ptr is built with brace enclosed direct initialization, use // parenthesis instead. if (Construct->isListInitialization()) { - SourceRange BraceRange = Construct->getParenOrBraceRange(); + const SourceRange BraceRange = Construct->getParenOrBraceRange(); Diag << FixItHint::CreateReplacement( CharSourceRange::getCharRange( BraceRange.getBegin(), BraceRange.getBegin().getLocWithOffset(1)), @@ -220,13 +220,13 @@ void MakeSmartPtrCheck::checkReset(SourceManager &SM, ASTContext *Ctx, const CXXMemberCallExpr *Reset, const CXXNewExpr *New) { const auto *Expr = cast<MemberExpr>(Reset->getCallee()); - SourceLocation OperatorLoc = Expr->getOperatorLoc(); - SourceLocation ResetCallStart = Reset->getExprLoc(); - SourceLocation ExprStart = Expr->getBeginLoc(); - SourceLocation ExprEnd = + const SourceLocation OperatorLoc = Expr->getOperatorLoc(); + const SourceLocation ResetCallStart = Reset->getExprLoc(); + const SourceLocation ExprStart = Expr->getBeginLoc(); + const SourceLocation ExprEnd = Lexer::getLocForEndOfToken(Expr->getEndLoc(), 0, SM, getLangOpts()); - bool InMacro = ExprStart.isMacroID(); + const bool InMacro = ExprStart.isMacroID(); if (InMacro && IgnoreMacros) { return; @@ -267,7 +267,7 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag, const CXXNewExpr *New, SourceManager &SM, ASTContext *Ctx) { auto SkipParensParents = [&](const Expr *E) { - TraversalKindScope RAII(*Ctx, TK_AsIs); + const TraversalKindScope RAII(*Ctx, TK_AsIs); for (const Expr *OldE = nullptr; E != OldE;) { OldE = E; @@ -281,9 +281,9 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag, return E; }; - SourceRange NewRange = SkipParensParents(New)->getSourceRange(); - SourceLocation NewStart = NewRange.getBegin(); - SourceLocation NewEnd = NewRange.getEnd(); + const SourceRange NewRange = SkipParensParents(New)->getSourceRange(); + const SourceLocation NewStart = NewRange.getBegin(); + const SourceLocation NewEnd = NewRange.getEnd(); // Skip when the source location of the new expression is invalid. if (NewStart.isInvalid() || NewEnd.isInvalid()) @@ -362,7 +362,7 @@ bool MakeSmartPtrCheck::replaceNew(DiagnosticBuilder &Diag, return false; } if (ArraySizeExpr.empty()) { - SourceRange InitRange = New->getDirectInitRange(); + const SourceRange InitRange = New->getDirectInitRange(); Diag << FixItHint::CreateRemoval( SourceRange(NewStart, InitRange.getBegin())); Diag << FixItHint::CreateRemoval(SourceRange(InitRange.getEnd(), NewEnd)); diff --git a/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp index b5a985b..f459295 100644 --- a/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp @@ -243,7 +243,6 @@ void MinMaxUseInitializerListCheck::registerPPCallbacks( void MinMaxUseInitializerListCheck::check( const MatchFinder::MatchResult &Match) { - const auto *TopCall = Match.Nodes.getNodeAs<CallExpr>("topCall"); const FindArgsResult Result = findArgs(TopCall); diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 360e2b8..a410f8d 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModuleRegistry.h" #include "AvoidBindCheck.h" #include "AvoidCArraysCheck.h" +#include "AvoidCStyleCastCheck.h" #include "AvoidSetjmpLongjmpCheck.h" #include "AvoidVariadicFunctionsCheck.h" #include "ConcatNestedNamespacesCheck.h" @@ -65,6 +66,8 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck<AvoidBindCheck>("modernize-avoid-bind"); CheckFactories.registerCheck<AvoidCArraysCheck>("modernize-avoid-c-arrays"); + CheckFactories.registerCheck<AvoidCStyleCastCheck>( + "modernize-avoid-c-style-cast"); CheckFactories.registerCheck<AvoidSetjmpLongjmpCheck>( "modernize-avoid-setjmp-longjmp"); CheckFactories.registerCheck<AvoidVariadicFunctionsCheck>( diff --git a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp index d5ccbb7..09d98ee 100644 --- a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp @@ -24,7 +24,8 @@ static bool isFirstFriendOfSecond(const CXXRecordDecl *Friend, const CXXRecordDecl *Class) { return llvm::any_of( Class->friends(), [Friend](FriendDecl *FriendDecl) -> bool { - if (TypeSourceInfo *FriendTypeSource = FriendDecl->getFriendType()) { + if (const TypeSourceInfo *FriendTypeSource = + FriendDecl->getFriendType()) { const QualType FriendType = FriendTypeSource->getType(); return FriendType->getAsCXXRecordDecl() == Friend; } @@ -195,11 +196,7 @@ static bool hasRValueOverload(const CXXConstructorDecl *Ctor, return true; }; - for (const auto *Candidate : Record->ctors()) { - if (IsRValueOverload(Candidate)) - return true; - } - return false; + return llvm::any_of(Record->ctors(), IsRValueOverload); } /// Find all references to \p ParamDecl across all of the @@ -208,7 +205,7 @@ static SmallVector<const ParmVarDecl *, 2> collectParamDecls(const CXXConstructorDecl *Ctor, const ParmVarDecl *ParamDecl) { SmallVector<const ParmVarDecl *, 2> Results; - unsigned ParamIdx = ParamDecl->getFunctionScopeIndex(); + const unsigned ParamIdx = ParamDecl->getFunctionScopeIndex(); for (const FunctionDecl *Redecl : Ctor->redecls()) Results.push_back(Redecl->getParamDecl(ParamIdx)); @@ -275,7 +272,7 @@ void PassByValueCheck::check(const MatchFinder::MatchResult &Result) { const auto *ParamDecl = Result.Nodes.getNodeAs<ParmVarDecl>("Param"); const auto *Initializer = Result.Nodes.getNodeAs<CXXCtorInitializer>("Initializer"); - SourceManager &SM = *Result.SourceManager; + const SourceManager &SM = *Result.SourceManager; // If the parameter is used or anything other than the copy, do not apply // the changes. @@ -299,7 +296,7 @@ void PassByValueCheck::check(const MatchFinder::MatchResult &Result) { if (ParamDecl->getType()->isLValueReferenceType()) { // Check if we can succesfully rewrite all declarations of the constructor. for (const ParmVarDecl *ParmDecl : collectParamDecls(Ctor, ParamDecl)) { - TypeLoc ParamTL = ParmDecl->getTypeSourceInfo()->getTypeLoc(); + const TypeLoc ParamTL = ParmDecl->getTypeSourceInfo()->getTypeLoc(); auto RefTL = ParamTL.getAs<ReferenceTypeLoc>(); if (RefTL.isNull()) { // We cannot rewrite this instance. The type is probably hidden behind @@ -309,11 +306,11 @@ void PassByValueCheck::check(const MatchFinder::MatchResult &Result) { } // Rewrite all declarations. for (const ParmVarDecl *ParmDecl : collectParamDecls(Ctor, ParamDecl)) { - TypeLoc ParamTL = ParmDecl->getTypeSourceInfo()->getTypeLoc(); + const TypeLoc ParamTL = ParmDecl->getTypeSourceInfo()->getTypeLoc(); auto RefTL = ParamTL.getAs<ReferenceTypeLoc>(); - TypeLoc ValueTL = RefTL.getPointeeLoc(); - CharSourceRange TypeRange = CharSourceRange::getTokenRange( + const TypeLoc ValueTL = RefTL.getPointeeLoc(); + const CharSourceRange TypeRange = CharSourceRange::getTokenRange( ParmDecl->getBeginLoc(), ParamTL.getEndLoc()); std::string ValueStr = Lexer::getSourceText( diff --git a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp index 8e514e4..2c4bddf 100644 --- a/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/RawStringLiteralCheck.cpp @@ -51,11 +51,11 @@ static bool containsEscapedCharacters(const MatchFinder::MatchResult &Result, if (DisallowedChars.test(C)) return false; - CharSourceRange CharRange = Lexer::makeFileCharRange( + const CharSourceRange CharRange = Lexer::makeFileCharRange( CharSourceRange::getTokenRange(Literal->getSourceRange()), *Result.SourceManager, Result.Context->getLangOpts()); - StringRef Text = Lexer::getSourceText(CharRange, *Result.SourceManager, - Result.Context->getLangOpts()); + const StringRef Text = Lexer::getSourceText(CharRange, *Result.SourceManager, + Result.Context->getLangOpts()); if (Text.empty() || isRawStringLiteral(Text)) return false; @@ -116,7 +116,7 @@ createUserDefinedSuffix(const StringLiteral *Literal, const SourceManager &SM, const CharSourceRange CharRange = Lexer::makeFileCharRange(TokenRange, SM, LangOpts); if (T.hasUDSuffix()) { - StringRef Text = Lexer::getSourceText(CharRange, SM, LangOpts); + const StringRef Text = Lexer::getSourceText(CharRange, SM, LangOpts); const size_t UDSuffixPos = Text.find_last_of('"'); if (UDSuffixPos == StringRef::npos) return std::nullopt; @@ -135,7 +135,7 @@ static std::string createRawStringLiteral(const StringLiteral *Literal, Delimiter = (I == 0) ? DelimiterStem : DelimiterStem + std::to_string(I); } - std::optional<StringRef> UserDefinedSuffix = + const std::optional<StringRef> UserDefinedSuffix = createUserDefinedSuffix(Literal, SM, LangOpts); if (Delimiter.empty()) diff --git a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp index 38b30f7..aa2db21 100644 --- a/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp @@ -89,9 +89,9 @@ void RedundantVoidArgCheck::check(const MatchFinder::MatchResult &Result) { void RedundantVoidArgCheck::processFunctionDecl( const MatchFinder::MatchResult &Result, const FunctionDecl *Function) { const auto *Method = dyn_cast<CXXMethodDecl>(Function); - SourceLocation Start = Method && Method->getParent()->isLambda() - ? Method->getBeginLoc() - : Function->getLocation(); + const SourceLocation Start = Method && Method->getParent()->isLambda() + ? Method->getBeginLoc() + : Function->getLocation(); SourceLocation End = Function->getEndLoc(); if (Function->isThisDeclarationADefinition()) { if (const Stmt *Body = Function->getBody()) { @@ -113,7 +113,8 @@ static bool isMacroIdentifier(const IdentifierTable &Idents, if (!ProtoToken.is(tok::TokenKind::raw_identifier)) return false; - IdentifierTable::iterator It = Idents.find(ProtoToken.getRawIdentifier()); + const IdentifierTable::iterator It = + Idents.find(ProtoToken.getRawIdentifier()); if (It == Idents.end()) return false; @@ -123,7 +124,7 @@ static bool isMacroIdentifier(const IdentifierTable &Idents, void RedundantVoidArgCheck::removeVoidArgumentTokens( const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range, StringRef GrammarLocation) { - CharSourceRange CharRange = + const CharSourceRange CharRange = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(Range), *Result.SourceManager, getLangOpts()); @@ -145,7 +146,7 @@ void RedundantVoidArgCheck::removeVoidArgumentTokens( Token ProtoToken; const IdentifierTable &Idents = Result.Context->Idents; int MacroLevel = 0; - std::string Diagnostic = + const std::string Diagnostic = ("redundant void argument list in " + GrammarLocation).str(); while (!PrototypeLexer.LexFromRawLexer(ProtoToken)) { @@ -216,7 +217,7 @@ void RedundantVoidArgCheck::removeVoidArgumentTokens( void RedundantVoidArgCheck::removeVoidToken(Token VoidToken, StringRef Diagnostic) { - SourceLocation VoidLoc = VoidToken.getLocation(); + const SourceLocation VoidLoc = VoidToken.getLocation(); diag(VoidLoc, Diagnostic) << FixItHint::CreateRemoval(VoidLoc); } @@ -239,9 +240,9 @@ void RedundantVoidArgCheck::processFieldDecl( void RedundantVoidArgCheck::processVarDecl( const MatchFinder::MatchResult &Result, const VarDecl *Var) { if (protoTypeHasNoParms(Var->getType())) { - SourceLocation Begin = Var->getBeginLoc(); + const SourceLocation Begin = Var->getBeginLoc(); if (Var->hasInit()) { - SourceLocation InitStart = + const SourceLocation InitStart = Result.SourceManager->getExpansionLoc(Var->getInit()->getBeginLoc()) .getLocWithOffset(-1); removeVoidArgumentTokens(Result, SourceRange(Begin, InitStart), @@ -273,8 +274,9 @@ void RedundantVoidArgCheck::processLambdaExpr( const MatchFinder::MatchResult &Result, const LambdaExpr *Lambda) { if (Lambda->getLambdaClass()->getLambdaCallOperator()->getNumParams() == 0 && Lambda->hasExplicitParameters()) { - SourceManager *SM = Result.SourceManager; - TypeLoc TL = Lambda->getLambdaClass()->getLambdaTypeInfo()->getTypeLoc(); + const SourceManager *SM = Result.SourceManager; + const TypeLoc TL = + Lambda->getLambdaClass()->getLambdaTypeInfo()->getTypeLoc(); removeVoidArgumentTokens(Result, {SM->getSpellingLoc(TL.getBeginLoc()), SM->getSpellingLoc(TL.getEndLoc())}, diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp index b562ae8..d0577ae 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp @@ -96,10 +96,10 @@ void ReplaceAutoPtrCheck::registerPPCallbacks(const SourceManager &SM, } void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) { - SourceManager &SM = *Result.SourceManager; + const SourceManager &SM = *Result.SourceManager; if (const auto *E = Result.Nodes.getNodeAs<Expr>(AutoPtrOwnershipTransferId)) { - CharSourceRange Range = Lexer::makeFileCharRange( + const CharSourceRange Range = Lexer::makeFileCharRange( CharSourceRange::getTokenRange(E->getSourceRange()), SM, LangOptions()); if (Range.isInvalid()) @@ -140,7 +140,8 @@ void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) { "auto_ptr") return; - SourceLocation EndLoc = AutoPtrLoc.getLocWithOffset(strlen("auto_ptr") - 1); + const SourceLocation EndLoc = + AutoPtrLoc.getLocWithOffset(strlen("auto_ptr") - 1); diag(AutoPtrLoc, "auto_ptr is deprecated, use unique_ptr instead") << FixItHint::CreateReplacement(SourceRange(AutoPtrLoc, EndLoc), "unique_ptr"); diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceDisallowCopyAndAssignMacroCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceDisallowCopyAndAssignMacroCheck.cpp index 64b0029..be5e21d 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceDisallowCopyAndAssignMacroCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceDisallowCopyAndAssignMacroCheck.cpp @@ -26,7 +26,7 @@ public: void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override { - IdentifierInfo *Info = MacroNameTok.getIdentifierInfo(); + const IdentifierInfo *Info = MacroNameTok.getIdentifierInfo(); if (!Info || !Args || Args->getNumMacroArguments() != 1) return; if (Info->getName() != Check.getMacroName()) @@ -38,11 +38,11 @@ public: // For now we only support simple argument that don't need to be // pre-expanded. return; - clang::IdentifierInfo *ClassIdent = ClassNameTok->getIdentifierInfo(); + const clang::IdentifierInfo *ClassIdent = ClassNameTok->getIdentifierInfo(); if (!ClassIdent) return; - std::string Replacement = llvm::formatv( + const std::string Replacement = llvm::formatv( R"cpp({0}(const {0} &) = delete; const {0} &operator=(const {0} &) = delete{1})cpp", ClassIdent->getName(), shouldAppendSemi(Range) ? ";" : ""); diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp index 3d7b3ea..cfc546a 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp @@ -78,7 +78,7 @@ void ReplaceRandomShuffleCheck::check(const MatchFinder::MatchResult &Result) { }(); std::string NewName = "shuffle"; - StringRef ContainerText = Lexer::getSourceText( + const StringRef ContainerText = Lexer::getSourceText( CharSourceRange::getTokenRange(MatchedDecl->getSourceRange()), *Result.SourceManager, getLangOpts()); if (ContainerText.starts_with("std::")) diff --git a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp index eba2445..15b64bc 100644 --- a/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ReturnBracedInitListCheck.cpp @@ -54,7 +54,7 @@ void ReturnBracedInitListCheck::check(const MatchFinder::MatchResult &Result) { Result.Nodes.getNodeAs<CXXConstructExpr>("ctor"); // Don't make replacements in macro. - SourceLocation Loc = MatchedConstructExpr->getExprLoc(); + const SourceLocation Loc = MatchedConstructExpr->getExprLoc(); if (Loc.isMacroID()) return; @@ -88,7 +88,7 @@ void ReturnBracedInitListCheck::check(const MatchFinder::MatchResult &Result) { } // Range for constructor name and opening brace. - CharSourceRange CtorCallSourceRange = CharSourceRange::getTokenRange( + const CharSourceRange CtorCallSourceRange = CharSourceRange::getTokenRange( Loc, CallParensRange.getBegin().getLocWithOffset(-1)); Diag << FixItHint::CreateRemoval(CtorCallSourceRange) diff --git a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp index 6078013..06982b8 100644 --- a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp @@ -286,7 +286,7 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *TL = Result.Nodes.getNodeAs<TypedefTypeLoc>(Bind)) { const NestedNameSpecifierLoc QualLoc = TL->getQualifierLoc(); - NestedNameSpecifier NNS = QualLoc.getNestedNameSpecifier(); + const NestedNameSpecifier NNS = QualLoc.getNestedNameSpecifier(); if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>( NNS.getAsRecordDecl())) { if (isNamedDeclInStdTraitsSet(CTSD, TypeTraits)) @@ -304,7 +304,7 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult &Result) { } if (const auto *DNTL = Result.Nodes.getNodeAs<DependentNameTypeLoc>(Bind)) { - NestedNameSpecifierLoc QualLoc = DNTL->getQualifierLoc(); + const NestedNameSpecifierLoc QualLoc = DNTL->getQualifierLoc(); if (checkTemplatedDecl(QualLoc.getNestedNameSpecifier(), TypeTraits)) EmitTypeWarning(QualLoc, DNTL->getEndLoc(), DNTL->getElaboratedKeywordLoc()); diff --git a/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.cpp index 4e4817f..28d8f75 100644 --- a/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UnaryStaticAssertCheck.cpp @@ -23,7 +23,7 @@ void UnaryStaticAssertCheck::check(const MatchFinder::MatchResult &Result) { const auto *AssertMessage = dyn_cast_if_present<StringLiteral>(MatchedDecl->getMessage()); - SourceLocation Loc = MatchedDecl->getLocation(); + const SourceLocation Loc = MatchedDecl->getLocation(); if (!AssertMessage || AssertMessage->getLength() || AssertMessage->getBeginLoc().isMacroID() || Loc.isMacroID()) diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp index 084349b..977ade1 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp @@ -101,7 +101,8 @@ AST_MATCHER_P(QualType, isSugarFor, Matcher<QualType>, SugarMatcher) { if (SugarMatcher.matches(QT, Finder, Builder)) return true; - QualType NewQT = QT.getSingleStepDesugaredType(Finder->getASTContext()); + const QualType NewQT = + QT.getSingleStepDesugaredType(Finder->getASTContext()); if (NewQT == QT) return false; QT = NewQT; @@ -147,18 +148,19 @@ static Matcher<NamedDecl> hasStdIteratorName() { /// recordDecl(hasStdContainerName()) matches \c vector and \c forward_list /// but not \c my_vec. static Matcher<NamedDecl> hasStdContainerName() { - static StringRef ContainerNames[] = {"array", "deque", - "forward_list", "list", - "vector", + static const StringRef ContainerNames[] = { + "array", "deque", + "forward_list", "list", + "vector", - "map", "multimap", - "set", "multiset", + "map", "multimap", + "set", "multiset", - "unordered_map", "unordered_multimap", - "unordered_set", "unordered_multiset", + "unordered_map", "unordered_multimap", + "unordered_set", "unordered_multiset", - "queue", "priority_queue", - "stack"}; + "queue", "priority_queue", + "stack"}; return hasAnyName(ContainerNames); } @@ -326,7 +328,8 @@ void UseAutoCheck::replaceIterators(const DeclStmt *D, ASTContext *Context) { // like function pointers. Not a concern since this action only works with // iterators but something to keep in mind in the future. - SourceRange Range(V->getTypeSourceInfo()->getTypeLoc().getSourceRange()); + const SourceRange Range( + V->getTypeSourceInfo()->getTypeLoc().getSourceRange()); diag(Range.getBegin(), "use auto when declaring iterators") << FixItHint::CreateReplacement(Range, "auto"); } @@ -342,7 +345,7 @@ static bool isMultiLevelPointerToTypeLocClasses( TypeLoc Loc, const std::initializer_list<TypeLoc::TypeLocClass> &LocClasses) { ignoreTypeLocClasses(Loc, {TypeLoc::Paren, TypeLoc::Qualified}); - TypeLoc::TypeLocClass TLC = Loc.getTypeLocClass(); + const TypeLoc::TypeLocClass TLC = Loc.getTypeLocClass(); if (TLC != TypeLoc::Pointer && TLC != TypeLoc::MemberPointer) return false; ignoreTypeLocClasses(Loc, {TypeLoc::Paren, TypeLoc::Qualified, @@ -359,7 +362,7 @@ void UseAutoCheck::replaceExpr( return; const QualType FirstDeclType = FirstDecl->getType().getCanonicalType(); - TypeSourceInfo *TSI = FirstDecl->getTypeSourceInfo(); + const TypeSourceInfo *TSI = FirstDecl->getTypeSourceInfo(); if (TSI == nullptr) return; @@ -409,7 +412,7 @@ void UseAutoCheck::replaceExpr( ignoreTypeLocClasses(Loc, {TypeLoc::Pointer, TypeLoc::Qualified}); ignoreTypeLocClasses(Loc, {TypeLoc::LValueReference, TypeLoc::RValueReference, TypeLoc::Qualified}); - SourceRange Range(Loc.getSourceRange()); + const SourceRange Range(Loc.getSourceRange()); if (MinTypeNameLength != 0 && getTypeNameLength(RemoveStars, @@ -420,17 +423,17 @@ void UseAutoCheck::replaceExpr( auto Diag = diag(Range.getBegin(), Message); - bool ShouldReplenishVariableName = isMultiLevelPointerToTypeLocClasses( + const bool ShouldReplenishVariableName = isMultiLevelPointerToTypeLocClasses( TSI->getTypeLoc(), {TypeLoc::FunctionProto, TypeLoc::ConstantArray}); // Space after 'auto' to handle cases where the '*' in the pointer type is // next to the identifier. This avoids changing 'int *p' into 'autop'. - llvm::StringRef Auto = ShouldReplenishVariableName - ? (RemoveStars ? "auto " : "auto *") - : (RemoveStars ? "auto " : "auto"); - std::string ReplenishedVariableName = + const llvm::StringRef Auto = ShouldReplenishVariableName + ? (RemoveStars ? "auto " : "auto *") + : (RemoveStars ? "auto " : "auto"); + const std::string ReplenishedVariableName = ShouldReplenishVariableName ? FirstDecl->getQualifiedNameAsString() : ""; - std::string Replacement = + const std::string Replacement = (Auto + llvm::StringRef{ReplenishedVariableName}).str(); Diag << FixItHint::CreateReplacement(Range, Replacement) << StarRemovals; } diff --git a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp index 8b5ffe8..6e21187 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseBoolLiteralsCheck.cpp @@ -50,14 +50,14 @@ void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) { void UseBoolLiteralsCheck::check(const MatchFinder::MatchResult &Result) { const auto *Literal = Result.Nodes.getNodeAs<IntegerLiteral>("literal"); const auto *Cast = Result.Nodes.getNodeAs<Expr>("cast"); - bool LiteralBooleanValue = Literal->getValue().getBoolValue(); + const bool LiteralBooleanValue = Literal->getValue().getBoolValue(); if (Literal->isInstantiationDependent()) return; const Expr *Expression = Cast ? Cast : Literal; - bool InMacro = Expression->getBeginLoc().isMacroID(); + const bool InMacro = Expression->getBeginLoc().isMacroID(); if (InMacro && IgnoreMacros) return; diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp index d5342a1..14874e3 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp @@ -55,7 +55,7 @@ static std::optional<TemplateSpecializationTypeLoc> matchEnableIfSpecializationImplTypename(TypeLoc TheType) { if (const auto Dep = TheType.getAs<DependentNameTypeLoc>()) { const IdentifierInfo *Identifier = Dep.getTypePtr()->getIdentifier(); - ElaboratedTypeKeyword Keyword = Dep.getTypePtr()->getKeyword(); + const ElaboratedTypeKeyword Keyword = Dep.getTypePtr()->getKeyword(); if (!Identifier || Identifier->getName() != "type" || (Keyword != ElaboratedTypeKeyword::Typename && Keyword != ElaboratedTypeKeyword::None)) { @@ -70,7 +70,6 @@ matchEnableIfSpecializationImplTypename(TypeLoc TheType) { if (const auto SpecializationLoc = TheType.getAs<TemplateSpecializationTypeLoc>()) { - const auto *Specialization = dyn_cast<TemplateSpecializationType>(SpecializationLoc.getTypePtr()); if (!Specialization) @@ -88,7 +87,7 @@ matchEnableIfSpecializationImplTypename(TypeLoc TheType) { if (!FirstParam || !FirstParam->getType()->isBooleanType()) return std::nullopt; - int NumArgs = SpecializationLoc.getNumArgs(); + const int NumArgs = SpecializationLoc.getNumArgs(); if (NumArgs != 1 && NumArgs != 2) return std::nullopt; @@ -101,7 +100,6 @@ static std::optional<TemplateSpecializationTypeLoc> matchEnableIfSpecializationImplTrait(TypeLoc TheType) { if (const auto SpecializationLoc = TheType.getAs<TemplateSpecializationTypeLoc>()) { - const auto *Specialization = dyn_cast<TemplateSpecializationType>(SpecializationLoc.getTypePtr()); if (!Specialization) @@ -124,7 +122,7 @@ matchEnableIfSpecializationImplTrait(TypeLoc TheType) { if (const auto *AliasedType = dyn_cast<DependentNameType>(Specialization->getAliasedType())) { - ElaboratedTypeKeyword Keyword = AliasedType->getKeyword(); + const ElaboratedTypeKeyword Keyword = AliasedType->getKeyword(); if (AliasedType->getIdentifier()->getName() != "type" || (Keyword != ElaboratedTypeKeyword::Typename && Keyword != ElaboratedTypeKeyword::None)) { @@ -133,7 +131,7 @@ matchEnableIfSpecializationImplTrait(TypeLoc TheType) { } else { return std::nullopt; } - int NumArgs = SpecializationLoc.getNumArgs(); + const int NumArgs = SpecializationLoc.getNumArgs(); if (NumArgs != 1 && NumArgs != 2) return std::nullopt; @@ -182,7 +180,6 @@ matchTrailingTemplateParam(const FunctionTemplateDecl *FunctionTemplate) { TemplateParams->getParam(TemplateParams->size() - 1); if (const auto *LastTemplateParam = dyn_cast<NonTypeTemplateParmDecl>(LastParam)) { - if (!LastTemplateParam->hasDefaultArgument() || !LastTemplateParam->getName().empty()) return {}; @@ -223,7 +220,7 @@ getConditionRange(ASTContext &Context, const LangOptions &LangOpts = Context.getLangOpts(); const SourceManager &SM = Context.getSourceManager(); if (EnableIf.getNumArgs() > 1) { - TemplateArgumentLoc NextArg = EnableIf.getArgLoc(1); + const TemplateArgumentLoc NextArg = EnableIf.getArgLoc(1); return {EnableIf.getLAngleLoc().getLocWithOffset(1), utils::lexer::findPreviousTokenKind( NextArg.getSourceRange().getBegin(), SM, LangOpts, tok::comma)}; @@ -235,7 +232,7 @@ getConditionRange(ASTContext &Context, static SourceRange getTypeRange(ASTContext &Context, const TemplateSpecializationTypeLoc &EnableIf) { - TemplateArgumentLoc Arg = EnableIf.getArgLoc(1); + const TemplateArgumentLoc Arg = EnableIf.getArgLoc(1); const LangOptions &LangOpts = Context.getLangOpts(); const SourceManager &SM = Context.getSourceManager(); return {utils::lexer::findPreviousTokenKind(Arg.getSourceRange().getBegin(), @@ -269,7 +266,7 @@ getTypeText(ASTContext &Context, static std::optional<SourceLocation> findInsertionForConstraint(const FunctionDecl *Function, ASTContext &Context) { - SourceManager &SM = Context.getSourceManager(); + const SourceManager &SM = Context.getSourceManager(); const LangOptions &LangOpts = Context.getLangOpts(); if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(Function)) { @@ -282,7 +279,7 @@ findInsertionForConstraint(const FunctionDecl *Function, ASTContext &Context) { return std::nullopt; } if (Function->isDeleted()) { - SourceLocation FunctionEnd = Function->getSourceRange().getEnd(); + const SourceLocation FunctionEnd = Function->getSourceRange().getEnd(); return utils::lexer::findNextAnyTokenKind(FunctionEnd, SM, LangOpts, tok::equal, tok::equal); } @@ -314,7 +311,7 @@ static bool isPrimaryExpression(const Expr *Expression) { static std::optional<std::string> getConditionText(const Expr *ConditionExpr, SourceRange ConditionRange, ASTContext &Context) { - SourceManager &SM = Context.getSourceManager(); + const SourceManager &SM = Context.getSourceManager(); const LangOptions &LangOpts = Context.getLangOpts(); SourceLocation PrevTokenLoc = ConditionRange.getEnd(); @@ -325,14 +322,14 @@ static std::optional<std::string> getConditionText(const Expr *ConditionExpr, Token PrevToken; std::tie(PrevToken, PrevTokenLoc) = utils::lexer::getPreviousTokenAndStart( PrevTokenLoc, SM, LangOpts, SkipComments); - bool EndsWithDoubleSlash = + const bool EndsWithDoubleSlash = PrevToken.is(tok::comment) && Lexer::getSourceText(CharSourceRange::getCharRange( PrevTokenLoc, PrevTokenLoc.getLocWithOffset(2)), SM, LangOpts) == "//"; bool Invalid = false; - llvm::StringRef ConditionText = Lexer::getSourceText( + const llvm::StringRef ConditionText = Lexer::getSourceText( CharSourceRange::getCharRange(ConditionRange), SM, LangOpts, &Invalid); if (Invalid) return std::nullopt; @@ -361,9 +358,9 @@ static std::vector<FixItHint> handleReturnType(const FunctionDecl *Function, const TypeLoc &ReturnType, const EnableIfData &EnableIf, ASTContext &Context) { - TemplateArgumentLoc EnableCondition = EnableIf.Loc.getArgLoc(0); + const TemplateArgumentLoc EnableCondition = EnableIf.Loc.getArgLoc(0); - SourceRange ConditionRange = getConditionRange(Context, EnableIf.Loc); + const SourceRange ConditionRange = getConditionRange(Context, EnableIf.Loc); std::optional<std::string> ConditionText = getConditionText( EnableCondition.getSourceExpression(), ConditionRange, Context); @@ -410,12 +407,12 @@ handleTrailingTemplateType(const FunctionTemplateDecl *FunctionTemplate, const FunctionDecl *Function, const Decl *LastTemplateParam, const EnableIfData &EnableIf, ASTContext &Context) { - SourceManager &SM = Context.getSourceManager(); + const SourceManager &SM = Context.getSourceManager(); const LangOptions &LangOpts = Context.getLangOpts(); - TemplateArgumentLoc EnableCondition = EnableIf.Loc.getArgLoc(0); + const TemplateArgumentLoc EnableCondition = EnableIf.Loc.getArgLoc(0); - SourceRange ConditionRange = getConditionRange(Context, EnableIf.Loc); + const SourceRange ConditionRange = getConditionRange(Context, EnableIf.Loc); std::optional<std::string> ConditionText = getConditionText( EnableCondition.getSourceExpression(), ConditionRange, Context); diff --git a/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp index 0d2c3a7..cc6b7bf 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp @@ -163,7 +163,7 @@ static bool isZero(const Expr *E) { case Stmt::IntegerLiteralClass: return !cast<IntegerLiteral>(E)->getValue(); case Stmt::FloatingLiteralClass: { - llvm::APFloat Value = cast<FloatingLiteral>(E)->getValue(); + const llvm::APFloat Value = cast<FloatingLiteral>(E)->getValue(); return Value.isZero() && !Value.isNegative(); } default: @@ -297,16 +297,16 @@ void UseDefaultMemberInitCheck::checkDefaultInit( }) > 1) return; - SourceLocation StartLoc = Field->getBeginLoc(); + const SourceLocation StartLoc = Field->getBeginLoc(); if (StartLoc.isMacroID() && IgnoreMacros) return; - SourceLocation FieldEnd = + const SourceLocation FieldEnd = Lexer::getLocForEndOfToken(Field->getSourceRange().getEnd(), 0, *Result.SourceManager, getLangOpts()); - SourceLocation LParenEnd = Lexer::getLocForEndOfToken( + const SourceLocation LParenEnd = Lexer::getLocForEndOfToken( Init->getLParenLoc(), 0, *Result.SourceManager, getLangOpts()); - CharSourceRange InitRange = + const CharSourceRange InitRange = CharSourceRange::getCharRange(LParenEnd, Init->getRParenLoc()); const Expr *InitExpression = Init->getInit(); diff --git a/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.cpp index c1094b1..e798f6f 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseDesignatedInitializersCheck.cpp @@ -49,7 +49,6 @@ static unsigned getNumberOfDesignated(const InitListExpr *SyntacticInitList) { namespace { struct Designators { - Designators(const InitListExpr *InitList) : InitList(InitList) { assert(InitList->isSyntacticForm()); }; @@ -152,7 +151,7 @@ void UseDesignatedInitializersCheck::check( if (IgnoreMacros && InitList->getBeginLoc().isMacroID()) return; { - DiagnosticBuilder Diag = + const DiagnosticBuilder Diag = diag(InitList->getLBraceLoc(), "use designated initializer list to initialize %0"); Diag << InitList->getType() << InitList->getSourceRange(); diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp index e585dd1..ca97b11 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -44,17 +44,12 @@ AST_MATCHER_P(NamedDecl, hasAnyNameIgnoringTemplates, std::vector<StringRef>, // clang/lib/ASTMatchers/ASTMatchersInternal.cpp and checks whether // FullNameTrimmed matches any of the given Names. const StringRef FullNameTrimmedRef = FullNameTrimmed; - for (const StringRef Pattern : Names) { - if (Pattern.starts_with("::")) { - if (FullNameTrimmed == Pattern) - return true; - } else if (FullNameTrimmedRef.ends_with(Pattern) && - FullNameTrimmedRef.drop_back(Pattern.size()).ends_with("::")) { - return true; - } - } - - return false; + return llvm::any_of(Names, [&](const StringRef Pattern) { + if (Pattern.starts_with("::")) + return FullNameTrimmed == Pattern; + return FullNameTrimmedRef.ends_with(Pattern) && + FullNameTrimmedRef.drop_back(Pattern.size()).ends_with("::"); + }); } // Checks if the given matcher is the last argument of the given CallExpr. diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp index d6ddbb6..fde9c73 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp @@ -200,7 +200,7 @@ static bool isCopyAssignmentAndCanBeDefaulted(ASTContext *Context, /// Returns false if the body has any non-whitespace character. static bool bodyEmpty(const ASTContext *Context, const CompoundStmt *Body) { bool Invalid = false; - StringRef Text = Lexer::getSourceText( + const StringRef Text = Lexer::getSourceText( CharSourceRange::getCharRange(Body->getLBracLoc().getLocWithOffset(1), Body->getRBracLoc()), Context->getSourceManager(), Context->getLangOpts(), &Invalid); @@ -306,8 +306,8 @@ void UseEqualsDefaultCheck::check(const MatchFinder::MatchResult &Result) { return; // If there are comments inside the body, don't do the change. - bool ApplyFix = SpecialFunctionDecl->isCopyAssignmentOperator() || - bodyEmpty(Result.Context, Body); + const bool ApplyFix = SpecialFunctionDecl->isCopyAssignmentOperator() || + bodyEmpty(Result.Context, Body); std::vector<FixItHint> RemoveInitializers; unsigned MemberType = 0; @@ -345,14 +345,14 @@ void UseEqualsDefaultCheck::check(const MatchFinder::MatchResult &Result) { Diag << MemberType; if (ApplyFix) { - SourceLocation UnifiedEnd = utils::lexer::getUnifiedEndLoc( + const SourceLocation UnifiedEnd = utils::lexer::getUnifiedEndLoc( *Body, Result.Context->getSourceManager(), Result.Context->getLangOpts()); // Skipping comments, check for a semicolon after Body->getSourceRange() std::optional<Token> Token = utils::lexer::findNextTokenSkippingComments( UnifiedEnd, Result.Context->getSourceManager(), Result.Context->getLangOpts()); - StringRef Replacement = + const StringRef Replacement = Token && Token->is(tok::semi) ? "= default" : "= default;"; Diag << FixItHint::CreateReplacement(Body->getSourceRange(), Replacement) << RemoveInitializers; diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp index ab2d41a..a19d2ec 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp @@ -74,7 +74,7 @@ void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) { void UseEqualsDeleteCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *Func = Result.Nodes.getNodeAs<CXXMethodDecl>(SpecialFunction)) { - SourceLocation EndLoc = Lexer::getLocForEndOfToken( + const SourceLocation EndLoc = Lexer::getLocForEndOfToken( Func->getEndLoc(), 0, *Result.SourceManager, getLangOpts()); if (IgnoreMacros && Func->getLocation().isMacroID()) diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp index 35320e8..574cbea 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp @@ -146,7 +146,7 @@ void UseIntegerSignComparisonCheck::check( R3.setBegin(Lexer::getLocForEndOfToken( SubExprRHS->getEndLoc(), 0, *Result.SourceManager, getLangOpts())); } - DiagnosticBuilder Diag = + const DiagnosticBuilder Diag = diag(BinaryOp->getBeginLoc(), "comparison between 'signed' and 'unsigned' integers"); StringRef CmpNamespace; diff --git a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp index d22c993..7e8d982 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNodiscardCheck.cpp @@ -110,11 +110,11 @@ void UseNodiscardCheck::registerMatchers(MatchFinder *Finder) { void UseNodiscardCheck::check(const MatchFinder::MatchResult &Result) { const auto *MatchedDecl = Result.Nodes.getNodeAs<CXXMethodDecl>("no_discard"); // Don't make replacements if the location is invalid or in a macro. - SourceLocation Loc = MatchedDecl->getLocation(); + const SourceLocation Loc = MatchedDecl->getLocation(); if (Loc.isInvalid() || Loc.isMacroID()) return; - SourceLocation RetLoc = MatchedDecl->getInnerLocStart(); + const SourceLocation RetLoc = MatchedDecl->getInnerLocStart(); ASTContext &Context = *Result.Context; diff --git a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp index d1388dc..6bd5485 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp @@ -81,12 +81,12 @@ void UseNoexceptCheck::check(const MatchFinder::MatchResult &Result) { assert(Range.isValid() && "Exception Source Range is invalid."); - CharSourceRange CRange = Lexer::makeFileCharRange( + const CharSourceRange CRange = Lexer::makeFileCharRange( CharSourceRange::getTokenRange(Range), *Result.SourceManager, Result.Context->getLangOpts()); - bool IsNoThrow = FnTy->isNothrow(); - StringRef ReplacementStr = + const bool IsNoThrow = FnTy->isNothrow(); + const StringRef ReplacementStr = IsNoThrow ? NoexceptMacro.empty() ? "noexcept" : NoexceptMacro : NoexceptMacro.empty() ? (DtorOrOperatorDel || UseNoexceptFalse) ? "noexcept(false)" : "" diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp index b6834c6..928a007 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp @@ -92,12 +92,13 @@ static bool isReplaceableRange(SourceLocation StartLoc, SourceLocation EndLoc, /// Returns true if and only if a replacement was made. static void replaceWithNullptr(ClangTidyCheck &Check, SourceManager &SM, SourceLocation StartLoc, SourceLocation EndLoc) { - CharSourceRange Range(SourceRange(StartLoc, EndLoc), true); + const CharSourceRange Range(SourceRange(StartLoc, EndLoc), true); // Add a space if nullptr follows an alphanumeric character. This happens // whenever there is an c-style explicit cast to nullptr not surrounded by // parentheses and right beside a return statement. - SourceLocation PreviousLocation = StartLoc.getLocWithOffset(-1); - bool NeedsSpace = isAlphanumeric(*SM.getCharacterData(PreviousLocation)); + const SourceLocation PreviousLocation = StartLoc.getLocWithOffset(-1); + const bool NeedsSpace = + isAlphanumeric(*SM.getCharacterData(PreviousLocation)); Check.diag(Range.getBegin(), "use nullptr") << FixItHint::CreateReplacement( Range, NeedsSpace ? " nullptr" : "nullptr"); } @@ -136,7 +137,7 @@ public: } bool TraverseStmt(Stmt *S) { - bool VisitedPreviously = Visited; + const bool VisitedPreviously = Visited; if (!RecursiveASTVisitor<MacroArgUsageVisitor>::TraverseStmt(S)) return false; @@ -258,8 +259,8 @@ public: // If the location comes from a macro body expansion, check to see if its // coming from one of the allowed 'NULL' macros. if (SM.isMacroArgExpansion(StartLoc) && SM.isMacroArgExpansion(EndLoc)) { - SourceLocation FileLocStart = SM.getFileLoc(StartLoc), - FileLocEnd = SM.getFileLoc(EndLoc); + const SourceLocation FileLocStart = SM.getFileLoc(StartLoc), + FileLocEnd = SM.getFileLoc(EndLoc); SourceLocation ImmediateMacroArgLoc, MacroLoc; // Skip NULL macros used in macro. if (!getMacroAndArgLocations(StartLoc, ImmediateMacroArgLoc, MacroLoc) || @@ -274,7 +275,7 @@ public: } if (SM.isMacroBodyExpansion(StartLoc) && SM.isMacroBodyExpansion(EndLoc)) { - StringRef OutermostMacroName = + const StringRef OutermostMacroName = getOutermostMacroName(StartLoc, SM, Context.getLangOpts()); // Check to see if the user wants to replace the macro being expanded. @@ -302,7 +303,7 @@ private: /// Tests that all expansions of a macro arg, one of which expands to /// result in \p CE, yield NullTo(Member)Pointer casts. bool allArgUsesValid(const CastExpr *CE) { - SourceLocation CastLoc = CE->getBeginLoc(); + const SourceLocation CastLoc = CE->getBeginLoc(); // Step 1: Get location of macro arg and location of the macro the arg was // provided to. @@ -348,17 +349,17 @@ private: // Find the location of the immediate macro expansion. while (true) { - std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(ArgLoc); + const std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(ArgLoc); const SrcMgr::SLocEntry *E = &SM.getSLocEntry(LocInfo.first); const SrcMgr::ExpansionInfo &Expansion = E->getExpansion(); - SourceLocation OldArgLoc = ArgLoc; + const SourceLocation OldArgLoc = ArgLoc; ArgLoc = Expansion.getExpansionLocStart(); if (!Expansion.isMacroArgExpansion()) { if (!MacroLoc.isFileID()) return false; - StringRef Name = + const StringRef Name = Lexer::getImmediateMacroName(OldArgLoc, SM, Context.getLangOpts()); return llvm::is_contained(NullMacros, Name); } @@ -371,7 +372,7 @@ private: // If spelling location resides in the same FileID as macro expansion // location, it means there is no inner macro. - FileID MacroFID = SM.getFileID(MacroLoc); + const FileID MacroFID = SM.getFileID(MacroLoc); if (SM.isInFileID(ArgLoc, MacroFID)) { // Don't transform this case. If the characters that caused the // null-conversion come from within a macro, they can't be changed. @@ -401,7 +402,7 @@ private: SourceLocation Loc = TestLoc, MacroLoc; while (true) { - std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); + const std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc); const SrcMgr::SLocEntry *E = &SM.getSLocEntry(LocInfo.first); const SrcMgr::ExpansionInfo &Expansion = E->getExpansion(); diff --git a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp index 6a19183..e2e7bba 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp @@ -35,7 +35,6 @@ void UseOverrideCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UseOverrideCheck::registerMatchers(MatchFinder *Finder) { - auto IgnoreDestructorMatcher = IgnoreDestructors ? cxxMethodDecl(unless(cxxDestructorDecl())) : cxxMethodDecl(); @@ -55,9 +54,9 @@ void UseOverrideCheck::registerMatchers(MatchFinder *Finder) { static SmallVector<Token, 16> parseTokens(CharSourceRange Range, const MatchFinder::MatchResult &Result) { const SourceManager &Sources = *Result.SourceManager; - std::pair<FileID, unsigned> LocInfo = + const std::pair<FileID, unsigned> LocInfo = Sources.getDecomposedLoc(Range.getBegin()); - StringRef File = Sources.getBufferData(LocInfo.first); + const StringRef File = Sources.getBufferData(LocInfo.first); const char *TokenBegin = File.data() + LocInfo.second; Lexer RawLexer(Sources.getLocForStartOfFile(LocInfo.first), Result.Context->getLangOpts(), File.begin(), TokenBegin, @@ -103,12 +102,12 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { Method->isOutOfLine()) return; - bool HasVirtual = Method->isVirtualAsWritten(); - bool HasOverride = Method->getAttr<OverrideAttr>(); - bool HasFinal = Method->getAttr<FinalAttr>(); + const bool HasVirtual = Method->isVirtualAsWritten(); + const bool HasOverride = Method->getAttr<OverrideAttr>(); + const bool HasFinal = Method->getAttr<FinalAttr>(); - bool OnlyVirtualSpecified = HasVirtual && !HasOverride && !HasFinal; - unsigned KeywordCount = HasVirtual + HasOverride + HasFinal; + const bool OnlyVirtualSpecified = HasVirtual && !HasOverride && !HasFinal; + const unsigned KeywordCount = HasVirtual + HasOverride + HasFinal; if ((!OnlyVirtualSpecified && KeywordCount == 1) || (!HasVirtual && HasOverride && HasFinal && AllowOverrideAndFinal)) @@ -120,12 +119,12 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { } else if (KeywordCount == 0) { Message = "annotate this function with '%0' or (rarely) '%1'"; } else { - StringRef Redundant = + const StringRef Redundant = HasVirtual ? (HasOverride && HasFinal && !AllowOverrideAndFinal ? "'virtual' and '%0' are" : "'virtual' is") : "'%0' is"; - StringRef Correct = HasFinal ? "'%1'" : "'%0'"; + const StringRef Correct = HasFinal ? "'%1'" : "'%0'"; Message = (llvm::Twine(Redundant) + " redundant since the function is already declared " + Correct) @@ -135,7 +134,7 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { auto Diag = diag(Method->getLocation(), Message) << OverrideSpelling << FinalSpelling; - CharSourceRange FileRange = Lexer::makeFileCharRange( + const CharSourceRange FileRange = Lexer::makeFileCharRange( CharSourceRange::getTokenRange(Method->getSourceRange()), Sources, getLangOpts()); @@ -151,9 +150,9 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { if (!HasFinal && !HasOverride) { SourceLocation InsertLoc; std::string ReplacementText = (OverrideSpelling + " ").str(); - SourceLocation MethodLoc = Method->getLocation(); + const SourceLocation MethodLoc = Method->getLocation(); - for (Token T : Tokens) { + for (const Token T : Tokens) { if (T.is(tok::kw___attribute) && !Sources.isBeforeInTranslationUnit(T.getLocation(), MethodLoc)) { InsertLoc = T.getLocation(); @@ -164,7 +163,7 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { if (Method->hasAttrs()) { for (const clang::Attr *A : Method->getAttrs()) { if (!A->isImplicit() && !A->isInherited()) { - SourceLocation Loc = + const SourceLocation Loc = Sources.getExpansionLoc(A->getRange().getBegin()); if ((!InsertLoc.isValid() || Sources.isBeforeInTranslationUnit(Loc, InsertLoc)) && @@ -221,13 +220,14 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { } if (HasFinal && HasOverride && !AllowOverrideAndFinal) { - SourceLocation OverrideLoc = Method->getAttr<OverrideAttr>()->getLocation(); + const SourceLocation OverrideLoc = + Method->getAttr<OverrideAttr>()->getLocation(); Diag << FixItHint::CreateRemoval( CharSourceRange::getTokenRange(OverrideLoc, OverrideLoc)); } if (HasVirtual) { - for (Token Tok : Tokens) { + for (const Token Tok : Tokens) { if (Tok.is(tok::kw_virtual)) { std::optional<Token> NextToken = utils::lexer::findNextTokenIncludingComments( diff --git a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp index 2e2f25f..529b5a43 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp @@ -135,7 +135,6 @@ class StdNumericReplacer : public StdReplacer { } // namespace utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { - utils::UseRangesCheck::ReplacerMap Result; // template<typename Iter> Func(Iter first, Iter last,...). diff --git a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp index 9bf3169..8849c33 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp @@ -74,7 +74,8 @@ findLocksInCompoundStmt(const CompoundStmt *Block, for (const Stmt *Stmt : Block->body()) { if (const auto *DS = dyn_cast<DeclStmt>(Stmt)) { - llvm::SmallVector<const VarDecl *> LockGuards = getLockGuardsFromDecl(DS); + const llvm::SmallVector<const VarDecl *> LockGuards = + getLockGuardsFromDecl(DS); if (!LockGuards.empty()) { CurrentLockGuardGroup.append(LockGuards); @@ -176,7 +177,7 @@ void UseScopedLockCheck::registerMatchers(MatchFinder *Finder) { void UseScopedLockCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *DS = Result.Nodes.getNodeAs<DeclStmt>("lock-decl-single")) { - llvm::SmallVector<const VarDecl *> Decls = getLockGuardsFromDecl(DS); + const llvm::SmallVector<const VarDecl *> Decls = getLockGuardsFromDecl(DS); diagOnMultipleLocks({Decls}, Result); return; } diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp index 414aa86..0315728 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdNumbersCheck.cpp @@ -81,16 +81,17 @@ AST_MATCHER_P(clang::Expr, anyOfExhaustive, std::vector<Matcher<clang::Stmt>>, // literals. struct MatchBuilder { auto - ignoreParenAndArithmeticCasting(const Matcher<clang::Expr> Matcher) const { + ignoreParenAndArithmeticCasting(const Matcher<clang::Expr> &Matcher) const { return expr(hasType(qualType(isArithmetic())), ignoringParenCasts(Matcher)); } - auto ignoreParenAndFloatingCasting(const Matcher<clang::Expr> Matcher) const { + auto + ignoreParenAndFloatingCasting(const Matcher<clang::Expr> &Matcher) const { return expr(hasType(qualType(isFloating())), ignoringParenCasts(Matcher)); } auto matchMathCall(const StringRef FunctionName, - const Matcher<clang::Expr> ArgumentMatcher) const { + const Matcher<clang::Expr> &ArgumentMatcher) const { auto HasAnyPrecisionName = hasAnyName( FunctionName, (FunctionName + "l").str(), (FunctionName + "f").str()); // Support long double(l) and float(f). @@ -100,7 +101,7 @@ struct MatchBuilder { hasArgument(0, ArgumentMatcher)))); } - auto matchSqrt(const Matcher<clang::Expr> ArgumentMatcher) const { + auto matchSqrt(const Matcher<clang::Expr> &ArgumentMatcher) const { return matchMathCall("sqrt", ArgumentMatcher); } @@ -148,7 +149,7 @@ struct MatchBuilder { return expr(anyOf(Int, Float, Dref)); } - auto match1Div(const Matcher<clang::Expr> Match) const { + auto match1Div(const Matcher<clang::Expr> &Match) const { return binaryOperator(hasOperatorName("/"), hasLHS(matchValue(1)), hasRHS(Match)); } @@ -307,7 +308,7 @@ UseStdNumbersCheck::UseStdNumbersCheck(const StringRef Name, void UseStdNumbersCheck::registerMatchers(MatchFinder *const Finder) { const auto Matches = MatchBuilder{DiffThreshold}; - std::vector<Matcher<clang::Stmt>> ConstantMatchers = { + const std::vector<Matcher<clang::Stmt>> ConstantMatchers = { Matches.matchLog2Euler(), Matches.matchLog10Euler(), Matches.matchEulerTopLevel(), Matches.matchEgamma(), Matches.matchInvSqrtPi(), Matches.matchInvPi(), diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp index 99ade04..1ab9576 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.cpp @@ -36,7 +36,6 @@ UseStdPrintCheck::UseStdPrintCheck(StringRef Name, ClangTidyContext *Context) utils::IncludeSorter::IS_LLVM), areDiagsSelfContained()), MaybeHeaderToInclude(Options.get("PrintHeader")) { - if (PrintfLikeFunctions.empty() && FprintfLikeFunctions.empty()) { PrintfLikeFunctions.emplace_back("::printf"); PrintfLikeFunctions.emplace_back("absl::PrintF"); @@ -70,8 +69,8 @@ void UseStdPrintCheck::registerPPCallbacks(const SourceManager &SM, this->PP = PP; } -static clang::ast_matchers::StatementMatcher -unusedReturnValue(clang::ast_matchers::StatementMatcher MatchedCallExpr) { +static clang::ast_matchers::StatementMatcher unusedReturnValue( + const clang::ast_matchers::StatementMatcher &MatchedCallExpr) { auto UnusedInCompoundStmt = compoundStmt(forEach(MatchedCallExpr), // The checker can't currently differentiate between the diff --git a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h index 18cff9a..7d771c4 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseStdPrintCheck.h @@ -36,7 +36,7 @@ public: } private: - Preprocessor *PP; + Preprocessor *PP = nullptr; bool StrictMode; std::vector<StringRef> PrintfLikeFunctions; std::vector<StringRef> FprintfLikeFunctions; diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp index d623ec4..02865b6 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp @@ -55,13 +55,12 @@ public: bool visitUnqualName(StringRef UnqualName) { // Check for collisions with function arguments. - for (ParmVarDecl *Param : F.parameters()) + Collision = llvm::any_of(F.parameters(), [&](const ParmVarDecl *Param) { if (const IdentifierInfo *Ident = Param->getIdentifier()) - if (Ident->getName() == UnqualName) { - Collision = true; - return true; - } - return false; + return Ident->getName() == UnqualName; + return false; + }); + return Collision; } bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) { @@ -126,7 +125,7 @@ public: } bool VisitDeclRefExpr(DeclRefExpr *S) { - DeclarationName Name = S->getNameInfo().getName(); + const DeclarationName Name = S->getNameInfo().getName(); return S->getQualifierLoc() || Name.isEmpty() || !Name.isIdentifier() || !visitUnqualName(Name.getAsIdentifierInfo()->getName()); } @@ -159,14 +158,14 @@ static SourceLocation findTrailingReturnTypeSourceLocation( const FunctionDecl &F, const FunctionTypeLoc &FTL, const ASTContext &Ctx, const SourceManager &SM, const LangOptions &LangOpts) { // We start with the location of the closing parenthesis. - SourceRange ExceptionSpecRange = F.getExceptionSpecSourceRange(); + const SourceRange ExceptionSpecRange = F.getExceptionSpecSourceRange(); if (ExceptionSpecRange.isValid()) return Lexer::getLocForEndOfToken(ExceptionSpecRange.getEnd(), 0, SM, LangOpts); // If the function argument list ends inside of a macro, it is dangerous to // start lexing from here - bail out. - SourceLocation ClosingParen = FTL.getRParenLoc(); + const SourceLocation ClosingParen = FTL.getRParenLoc(); if (ClosingParen.isMacroID()) return {}; @@ -174,8 +173,8 @@ static SourceLocation findTrailingReturnTypeSourceLocation( Lexer::getLocForEndOfToken(ClosingParen, 0, SM, LangOpts); // Skip subsequent CV and ref qualifiers. - std::pair<FileID, unsigned> Loc = SM.getDecomposedLoc(Result); - StringRef File = SM.getBufferData(Loc.first); + const std::pair<FileID, unsigned> Loc = SM.getDecomposedLoc(Result); + const StringRef File = SM.getBufferData(Loc.first); const char *TokenBegin = File.data() + Loc.second; Lexer Lexer(SM.getLocForStartOfFile(Loc.first), LangOpts, File.begin(), TokenBegin, File.end()); @@ -220,7 +219,7 @@ classifyToken(const FunctionDecl &F, Preprocessor &PP, Token Tok) { Token End; End.startToken(); End.setKind(tok::eof); - SmallVector<Token, 2> Stream{Tok, End}; + const SmallVector<Token, 2> Stream{Tok, End}; // FIXME: do not report these token to Preprocessor.TokenWatcher. PP.EnterTokenStream(Stream, false, /*IsReinject=*/false); @@ -230,8 +229,8 @@ classifyToken(const FunctionDecl &F, Preprocessor &PP, Token Tok) { if (T.is(tok::eof)) break; - bool Qual = isCvr(T); - bool Spec = isSpecifier(T); + const bool Qual = isCvr(T); + const bool Spec = isSpecifier(T); CT.IsQualifier &= Qual; CT.IsSpecifier &= Spec; ContainsQualifiers |= Qual; @@ -252,12 +251,12 @@ classifyTokensBeforeFunctionName(const FunctionDecl &F, const ASTContext &Ctx, const SourceManager &SM, const LangOptions &LangOpts, Preprocessor *PP) { - SourceLocation BeginF = expandIfMacroId(F.getBeginLoc(), SM); - SourceLocation BeginNameF = expandIfMacroId(F.getLocation(), SM); + const SourceLocation BeginF = expandIfMacroId(F.getBeginLoc(), SM); + const SourceLocation BeginNameF = expandIfMacroId(F.getLocation(), SM); // Create tokens for everything before the name of the function. - std::pair<FileID, unsigned> Loc = SM.getDecomposedLoc(BeginF); - StringRef File = SM.getBufferData(Loc.first); + const std::pair<FileID, unsigned> Loc = SM.getDecomposedLoc(BeginF); + const StringRef File = SM.getBufferData(Loc.first); const char *TokenBegin = File.data() + Loc.second; Lexer Lexer(SM.getLocForStartOfFile(Loc.first), LangOpts, File.begin(), TokenBegin, File.end()); @@ -305,7 +304,6 @@ static SourceRange findReturnTypeAndCVSourceRange(const FunctionDecl &F, const TypeLoc &ReturnLoc, const ASTContext &Ctx, const SourceManager &SM, const LangOptions &LangOpts, Preprocessor *PP) { - // We start with the range of the return type and expand to neighboring // qualifiers (const, volatile and restrict). SourceRange ReturnTypeRange = F.getReturnTypeSourceRange(); @@ -369,9 +367,9 @@ static SourceLocation findLambdaTrailingReturnInsertLoc( else ParamEndLoc = Method->getParametersSourceRange().getEnd(); - std::pair<FileID, unsigned> ParamEndLocInfo = + const std::pair<FileID, unsigned> ParamEndLocInfo = SM.getDecomposedLoc(ParamEndLoc); - StringRef Buffer = SM.getBufferData(ParamEndLocInfo.first); + const StringRef Buffer = SM.getBufferData(ParamEndLocInfo.first); Lexer Lexer(SM.getLocForStartOfFile(ParamEndLocInfo.first), LangOpts, Buffer.begin(), Buffer.data() + ParamEndLocInfo.second, @@ -421,11 +419,11 @@ static void keepSpecifiers(std::string &ReturnType, std::string &Auto, return; // Find specifiers, remove them from the return type, add them to 'auto'. - unsigned int ReturnTypeBeginOffset = + const unsigned int ReturnTypeBeginOffset = SM.getDecomposedLoc(ReturnTypeCVRange.getBegin()).second; - size_t InitialAutoLength = Auto.size(); + const size_t InitialAutoLength = Auto.size(); unsigned int DeletedChars = 0; - for (ClassifiedToken CT : *MaybeTokens) { + for (const ClassifiedToken CT : *MaybeTokens) { if (SM.isBeforeInTranslationUnit(CT.T.getLocation(), ReturnTypeCVRange.getBegin()) || SM.isBeforeInTranslationUnit(ReturnTypeCVRange.getEnd(), @@ -436,10 +434,11 @@ static void keepSpecifiers(std::string &ReturnType, std::string &Auto, // Add the token to 'auto' and remove it from the return type, including // any whitespace following the token. - unsigned int TOffset = SM.getDecomposedLoc(CT.T.getLocation()).second; + const unsigned int TOffset = SM.getDecomposedLoc(CT.T.getLocation()).second; assert(TOffset >= ReturnTypeBeginOffset && "Token location must be after the beginning of the return type"); - unsigned int TOffsetInRT = TOffset - ReturnTypeBeginOffset - DeletedChars; + const unsigned int TOffsetInRT = + TOffset - ReturnTypeBeginOffset - DeletedChars; unsigned int TLengthWithWS = CT.T.getLength(); while (TOffsetInRT + TLengthWithWS < ReturnType.size() && llvm::isSpace(ReturnType[TOffsetInRT + TLengthWithWS])) @@ -458,7 +457,6 @@ UseTrailingReturnTypeCheck::UseTrailingReturnTypeCheck( : ClangTidyCheck(Name, Context), TransformFunctions(Options.get("TransformFunctions", true)), TransformLambdas(Options.get("TransformLambdas", TransformLambda::All)) { - if (TransformFunctions == false && TransformLambdas == TransformLambda::None) this->configurationDiag( "The check 'modernize-use-trailing-return-type' will not perform any " @@ -548,7 +546,7 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) { return; } - SourceLocation InsertionLoc = + const SourceLocation InsertionLoc = findTrailingReturnTypeSourceLocation(*F, FTL, Ctx, SM, LangOpts); if (InsertionLoc.isInvalid()) { diag(F->getLocation(), ErrorMessageOnFunction); @@ -558,7 +556,7 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) { // Using the declared return type via F->getDeclaredReturnType().getAsString() // discards user formatting and order of const, volatile, type, whitespace, // space before & ... . - SourceRange ReturnTypeCVRange = findReturnTypeAndCVSourceRange( + const SourceRange ReturnTypeCVRange = findReturnTypeAndCVSourceRange( *F, FTL.getReturnLoc(), Ctx, SM, LangOpts, PP); if (ReturnTypeCVRange.isInvalid()) { diag(F->getLocation(), ErrorMessageOnFunction); @@ -580,13 +578,13 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) { return; } - SourceLocation ReturnTypeEnd = + const SourceLocation ReturnTypeEnd = Lexer::getLocForEndOfToken(ReturnTypeCVRange.getEnd(), 0, SM, LangOpts); - StringRef CharAfterReturnType = Lexer::getSourceText( + const StringRef CharAfterReturnType = Lexer::getSourceText( CharSourceRange::getCharRange(ReturnTypeEnd, ReturnTypeEnd.getLocWithOffset(1)), SM, LangOpts); - bool NeedSpaceAfterAuto = + const bool NeedSpaceAfterAuto = CharAfterReturnType.empty() || !llvm::isSpace(CharAfterReturnType[0]); std::string Auto = NeedSpaceAfterAuto ? "auto " : "auto"; @@ -603,7 +601,6 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) { void UseTrailingReturnTypeCheck::diagOnLambda( const LambdaExpr *Lambda, const ast_matchers::MatchFinder::MatchResult &Result) { - const CXXMethodDecl *Method = Lambda->getCallOperator(); if (!Method || Lambda->hasExplicitResultType()) return; diff --git a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp index 03ecec9..e3672f8 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp @@ -96,7 +96,7 @@ void UseTransparentFunctorsCheck::check( FunctorParentType->template_arguments()[ArgNum]; if (Arg.getKind() != TemplateArgument::Type) continue; - QualType ParentArgType = Arg.getAsType(); + const QualType ParentArgType = Arg.getAsType(); if (ParentArgType->isRecordType() && ParentArgType->getAsCXXRecordDecl() == Functor->getAsType()->getAsCXXRecordDecl()) @@ -105,13 +105,13 @@ void UseTransparentFunctorsCheck::check( // Functor is a default template argument. if (ArgNum == FunctorParentType->template_arguments().size()) return; - TemplateArgumentLoc FunctorLoc = FunctorParentLoc.getArgLoc(ArgNum); + const TemplateArgumentLoc FunctorLoc = FunctorParentLoc.getArgLoc(ArgNum); auto FunctorTypeLoc = getInnerTypeLocAs<TemplateSpecializationTypeLoc>( FunctorLoc.getTypeSourceInfo()->getTypeLoc()); if (FunctorTypeLoc.isNull()) return; - SourceLocation ReportLoc = FunctorLoc.getLocation(); + const SourceLocation ReportLoc = FunctorLoc.getLocation(); if (ReportLoc.isInvalid()) return; diag(ReportLoc, Message) << FuncClass->getName() diff --git a/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp index eef9d39..08c40d4 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp @@ -15,7 +15,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::modernize { void UseUncaughtExceptionsCheck::registerMatchers(MatchFinder *Finder) { - std::string MatchText = "::std::uncaught_exception"; + const std::string MatchText = "::std::uncaught_exception"; // Using declaration: warning and fix-it. Finder->addMatcher( @@ -78,7 +78,7 @@ void UseUncaughtExceptionsCheck::check(const MatchFinder::MatchResult &Result) { *Result.SourceManager, getLangOpts()); Text.consume_back("()"); - int TextLength = Text.size(); + const int TextLength = Text.size(); if (WarnOnly) { return; diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp index 7267375..38b3689 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp @@ -114,7 +114,7 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { if (ExternCDecl && IgnoreExternC) return; - SourceLocation StartLoc = MatchedDecl->getBeginLoc(); + const SourceLocation StartLoc = MatchedDecl->getBeginLoc(); if (StartLoc.isMacroID() && IgnoreMacros) return; @@ -172,7 +172,7 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { .str(), ExtraReference.str()}; }(); - StringRef Name = MatchedDecl->getName(); + const StringRef Name = MatchedDecl->getName(); SourceRange ReplaceRange = MatchedDecl->getSourceRange(); // typedefs with multiple comma-separated definitions produce multiple @@ -223,7 +223,8 @@ void UseUsingCheck::check(const MatchFinder::MatchResult &Result) { return; } - std::string Replacement = (Using + Name + " = " + Type + QualifierStr).str(); + const std::string Replacement = + (Using + Name + " = " + Type + QualifierStr).str(); Diag << FixItHint::CreateReplacement(ReplaceRange, Replacement); } } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h index 60813cd..07d15fa 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h @@ -18,7 +18,6 @@ namespace clang::tidy::modernize { /// For the user-facing documentation see: /// https://clang.llvm.org/extra/clang-tidy/checks/modernize/use-using.html class UseUsingCheck : public ClangTidyCheck { - const bool IgnoreMacros; const bool IgnoreExternC; SourceLocation LastReplacementEnd; diff --git a/clang-tools-extra/clang-tidy/objc/AssertEquals.cpp b/clang-tools-extra/clang-tidy/objc/AssertEqualsCheck.cpp index 9d274ee..a9e6a4b 100644 --- a/clang-tools-extra/clang-tidy/objc/AssertEquals.cpp +++ b/clang-tools-extra/clang-tidy/objc/AssertEqualsCheck.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "AssertEquals.h" +#include "AssertEqualsCheck.h" #include "llvm/ADT/StringMap.h" #include <string> @@ -21,7 +21,7 @@ static const llvm::StringMap<StringRef> NameMap{ {"XCTAssertNotEqual", "XCTAssertNotEqualObjects"}, }; -void AssertEquals::registerMatchers(MatchFinder *Finder) { +void AssertEqualsCheck::registerMatchers(MatchFinder *Finder) { for (const auto &[CurrName, _] : NameMap) { Finder->addMatcher( binaryOperator(anyOf(hasOperatorName("!="), hasOperatorName("==")), @@ -35,7 +35,8 @@ void AssertEquals::registerMatchers(MatchFinder *Finder) { } } -void AssertEquals::check(const ast_matchers::MatchFinder::MatchResult &Result) { +void AssertEqualsCheck::check( + const ast_matchers::MatchFinder::MatchResult &Result) { for (const auto &[CurrName, TargetName] : NameMap) { if (const auto *Root = Result.Nodes.getNodeAs<BinaryOperator>(CurrName)) { const SourceManager *Sm = Result.SourceManager; diff --git a/clang-tools-extra/clang-tidy/objc/AssertEquals.h b/clang-tools-extra/clang-tidy/objc/AssertEqualsCheck.h index 1405065..237daba 100644 --- a/clang-tools-extra/clang-tidy/objc/AssertEquals.h +++ b/clang-tools-extra/clang-tidy/objc/AssertEqualsCheck.h @@ -6,22 +6,22 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_ASSERTEQUALS_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_ASSERTEQUALS_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_ASSERTEQUALSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_ASSERTEQUALSCHECK_H #include "../ClangTidyCheck.h" #include "clang/ASTMatchers/ASTMatchFinder.h" namespace clang::tidy::objc { -/// Warn if XCTAssertEqual() or XCTAssertNotEqual() is used with at least one +/// Warns if XCTAssertEqual() or XCTAssertNotEqual() is used with at least one /// operands of type NSString*. /// /// For the user-facing documentation see: /// https://clang.llvm.org/extra/clang-tidy/checks/objc/assert-equals.html -class AssertEquals final : public ClangTidyCheck { +class AssertEqualsCheck final : public ClangTidyCheck { public: - AssertEquals(StringRef Name, ClangTidyContext *Context) + AssertEqualsCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.ObjC; @@ -32,4 +32,4 @@ public: } // namespace clang::tidy::objc -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_ASSERTEQUALS_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_ASSERTEQUALSCHECK_H diff --git a/clang-tools-extra/clang-tidy/objc/CMakeLists.txt b/clang-tools-extra/clang-tidy/objc/CMakeLists.txt index e28d25d..2908d11 100644 --- a/clang-tools-extra/clang-tidy/objc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/objc/CMakeLists.txt @@ -4,7 +4,7 @@ set(LLVM_LINK_COMPONENTS ) add_clang_library(clangTidyObjCModule STATIC - AssertEquals.cpp + AssertEqualsCheck.cpp AvoidNSErrorInitCheck.cpp DeallocInCategoryCheck.cpp ForbiddenSubclassingCheck.cpp diff --git a/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp b/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp index 7b48fd9..b8010e0 100644 --- a/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp @@ -25,11 +25,9 @@ AST_MATCHER_P(ObjCImplementationDecl, hasInterface, AST_MATCHER_P(ObjCContainerDecl, hasInstanceMethod, ast_matchers::internal::Matcher<ObjCMethodDecl>, Base) { // Check each instance method against the provided matcher. - for (const auto *I : Node.instance_methods()) { - if (Base.matches(*I, Finder, Builder)) - return true; - } - return false; + return llvm::any_of(Node.instance_methods(), [&](const ObjCMethodDecl *I) { + return Base.matches(*I, Finder, Builder); + }); } } // namespace diff --git a/clang-tools-extra/clang-tidy/objc/ObjCTidyModule.cpp b/clang-tools-extra/clang-tidy/objc/ObjCTidyModule.cpp index c21b459..411d252 100644 --- a/clang-tools-extra/clang-tidy/objc/ObjCTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/objc/ObjCTidyModule.cpp @@ -9,7 +9,7 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" -#include "AssertEquals.h" +#include "AssertEqualsCheck.h" #include "AvoidNSErrorInitCheck.h" #include "DeallocInCategoryCheck.h" #include "ForbiddenSubclassingCheck.h" @@ -29,7 +29,7 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck<AvoidNSErrorInitCheck>( "objc-avoid-nserror-init"); - CheckFactories.registerCheck<AssertEquals>("objc-assert-equals"); + CheckFactories.registerCheck<AssertEqualsCheck>("objc-assert-equals"); CheckFactories.registerCheck<DeallocInCategoryCheck>( "objc-dealloc-in-category"); diff --git a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp index d02ab72..5bd842b 100644 --- a/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp +++ b/clang-tools-extra/clang-tidy/openmp/UseDefaultNoneCheck.cpp @@ -37,8 +37,9 @@ void UseDefaultNoneCheck::check(const MatchFinder::MatchResult &Result) { "OpenMP directive '%0' specifies 'default(%1)' clause, consider using " "'default(none)' clause instead") << getOpenMPDirectiveName(Directive->getDirectiveKind()) - << getOpenMPSimpleClauseTypeName(Clause->getClauseKind(), - unsigned(Clause->getDefaultKind())); + << getOpenMPSimpleClauseTypeName( + Clause->getClauseKind(), + llvm::to_underlying(Clause->getDefaultKind())); diag(Clause->getBeginLoc(), "existing 'default' clause specified here", DiagnosticIDs::Note); return; diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt index c6e547c..9a2f900 100644 --- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt @@ -23,7 +23,7 @@ add_clang_library(clangTidyPerformanceModule STATIC PerformanceTidyModule.cpp TriviallyDestructibleCheck.cpp TypePromotionInMathFnCheck.cpp - UnnecessaryCopyInitialization.cpp + UnnecessaryCopyInitializationCheck.cpp UnnecessaryValueParamCheck.cpp LINK_LIBS diff --git a/clang-tools-extra/clang-tidy/performance/NoexceptSwapCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoexceptSwapCheck.cpp index 29faf9f..9ab6608 100644 --- a/clang-tools-extra/clang-tidy/performance/NoexceptSwapCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/NoexceptSwapCheck.cpp @@ -17,7 +17,6 @@ using namespace clang::ast_matchers; namespace clang::tidy::performance { void NoexceptSwapCheck::registerMatchers(MatchFinder *Finder) { - // Match non-const method with single argument that is non-const reference to // a class type that owns method and return void. // Matches: void Class::swap(Class&) diff --git a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp index ae15208..3497ea7 100644 --- a/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/performance/PerformanceTidyModule.cpp @@ -26,7 +26,7 @@ #include "NoexceptSwapCheck.h" #include "TriviallyDestructibleCheck.h" #include "TypePromotionInMathFnCheck.h" -#include "UnnecessaryCopyInitialization.h" +#include "UnnecessaryCopyInitializationCheck.h" #include "UnnecessaryValueParamCheck.h" namespace clang::tidy { @@ -66,7 +66,7 @@ public: "performance-trivially-destructible"); CheckFactories.registerCheck<TypePromotionInMathFnCheck>( "performance-type-promotion-in-math-fn"); - CheckFactories.registerCheck<UnnecessaryCopyInitialization>( + CheckFactories.registerCheck<UnnecessaryCopyInitializationCheck>( "performance-unnecessary-copy-initialization"); CheckFactories.registerCheck<UnnecessaryValueParamCheck>( "performance-unnecessary-value-param"); diff --git a/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp b/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp index 2f54b17..416c41d 100644 --- a/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/TriviallyDestructibleCheck.cpp @@ -23,12 +23,9 @@ namespace { AST_MATCHER(Decl, isFirstDecl) { return Node.isFirstDecl(); } AST_MATCHER_P(CXXRecordDecl, hasBase, Matcher<QualType>, InnerMatcher) { - for (const CXXBaseSpecifier &BaseSpec : Node.bases()) { - const QualType BaseType = BaseSpec.getType(); - if (InnerMatcher.matches(BaseType, Finder, Builder)) - return true; - } - return false; + return llvm::any_of(Node.bases(), [&](const CXXBaseSpecifier &BaseSpec) { + return InnerMatcher.matches(BaseSpec.getType(), Finder, Builder); + }); } } // namespace diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitializationCheck.cpp index fec4c14..e6fe857 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitializationCheck.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "UnnecessaryCopyInitialization.h" +#include "UnnecessaryCopyInitializationCheck.h" #include "../utils/DeclRefExprUtils.h" #include "../utils/FixItHintUtils.h" #include "../utils/LexerUtils.h" @@ -227,7 +227,7 @@ static QualType constructorArgumentType(const VarDecl *OldVar, return MethodDecl->getReturnType(); } -UnnecessaryCopyInitialization::UnnecessaryCopyInitialization( +UnnecessaryCopyInitializationCheck::UnnecessaryCopyInitializationCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), AllowedTypes( @@ -235,7 +235,7 @@ UnnecessaryCopyInitialization::UnnecessaryCopyInitialization( ExcludedContainerTypes(utils::options::parseStringList( Options.get("ExcludedContainerTypes", ""))) {} -void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) { +void UnnecessaryCopyInitializationCheck::registerMatchers(MatchFinder *Finder) { auto LocalVarCopiedFrom = [this](const ast_matchers::internal::Matcher<Expr> &CopyCtorArg) { return compoundStmt( @@ -276,7 +276,7 @@ void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) { this); } -void UnnecessaryCopyInitialization::check( +void UnnecessaryCopyInitializationCheck::check( const MatchFinder::MatchResult &Result) { const auto &NewVar = *Result.Nodes.getNodeAs<VarDecl>("newVarDecl"); const auto &BlockStmt = *Result.Nodes.getNodeAs<Stmt>("blockStmt"); @@ -325,7 +325,7 @@ void UnnecessaryCopyInitialization::check( } } -void UnnecessaryCopyInitialization::handleCopyFromMethodReturn( +void UnnecessaryCopyInitializationCheck::handleCopyFromMethodReturn( const CheckContext &Ctx, const VarDecl *ObjectArg) { const bool IsConstQualified = Ctx.Var.getType().isConstQualified(); if (!IsConstQualified && !Ctx.IsVarOnlyUsedAsConst) @@ -337,7 +337,7 @@ void UnnecessaryCopyInitialization::handleCopyFromMethodReturn( diagnoseCopyFromMethodReturn(Ctx); } -void UnnecessaryCopyInitialization::handleCopyFromLocalVar( +void UnnecessaryCopyInitializationCheck::handleCopyFromLocalVar( const CheckContext &Ctx, const VarDecl &OldVar) { if (!Ctx.IsVarOnlyUsedAsConst || !isInitializingVariableImmutable(OldVar, Ctx.BlockStmt, Ctx.ASTCtx, @@ -346,7 +346,7 @@ void UnnecessaryCopyInitialization::handleCopyFromLocalVar( diagnoseCopyFromLocalVar(Ctx, OldVar); } -void UnnecessaryCopyInitialization::diagnoseCopyFromMethodReturn( +void UnnecessaryCopyInitializationCheck::diagnoseCopyFromMethodReturn( const CheckContext &Ctx) { auto Diagnostic = diag(Ctx.Var.getLocation(), @@ -360,7 +360,7 @@ void UnnecessaryCopyInitialization::diagnoseCopyFromMethodReturn( maybeIssueFixes(Ctx, Diagnostic); } -void UnnecessaryCopyInitialization::diagnoseCopyFromLocalVar( +void UnnecessaryCopyInitializationCheck::diagnoseCopyFromLocalVar( const CheckContext &Ctx, const VarDecl &OldVar) { auto Diagnostic = diag(Ctx.Var.getLocation(), @@ -372,7 +372,7 @@ void UnnecessaryCopyInitialization::diagnoseCopyFromLocalVar( maybeIssueFixes(Ctx, Diagnostic); } -void UnnecessaryCopyInitialization::maybeIssueFixes( +void UnnecessaryCopyInitializationCheck::maybeIssueFixes( const CheckContext &Ctx, DiagnosticBuilder &Diagnostic) { if (Ctx.IssueFix) { if (Ctx.IsVarUnused) @@ -382,7 +382,7 @@ void UnnecessaryCopyInitialization::maybeIssueFixes( } } -void UnnecessaryCopyInitialization::storeOptions( +void UnnecessaryCopyInitializationCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "AllowedTypes", utils::options::serializeStringList(AllowedTypes)); diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitializationCheck.h index 5edc744..89957a5 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.h +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitializationCheck.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARYCOPYINITIALIZATION_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARYCOPYINITIALIZATION_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARYCOPYINITIALIZATIONCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARYCOPYINITIALIZATIONCHECK_H #include "../ClangTidyCheck.h" #include "clang/AST/Decl.h" @@ -22,9 +22,12 @@ namespace clang::tidy::performance { // The check currently only understands a subset of variables that are // guaranteed to outlive the const reference returned, namely: const variables, // const references, and const pointers to const. -class UnnecessaryCopyInitialization : public ClangTidyCheck { +// +// For the user-facing documentation see: +// https://clang.llvm.org/extra/clang-tidy/checks/performance/unnecessary-copy-initialization.html +class UnnecessaryCopyInitializationCheck : public ClangTidyCheck { public: - UnnecessaryCopyInitialization(StringRef Name, ClangTidyContext *Context); + UnnecessaryCopyInitializationCheck(StringRef Name, ClangTidyContext *Context); bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus; } @@ -64,4 +67,4 @@ private: } // namespace clang::tidy::performance -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARYCOPYINITIALIZATION_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_PERFORMANCE_UNNECESSARYCOPYINITIALIZATIONCHECK_H diff --git a/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h b/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h index 0dd6402..d66149a 100644 --- a/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h +++ b/clang-tools-extra/clang-tidy/portability/RestrictSystemIncludesCheck.h @@ -23,7 +23,7 @@ namespace clang::tidy::portability { class RestrictSystemIncludesCheck : public ClangTidyCheck { public: RestrictSystemIncludesCheck(StringRef Name, ClangTidyContext *Context, - std::string DefaultAllowedIncludes = "*") + StringRef DefaultAllowedIncludes = "*") : ClangTidyCheck(Name, Context), AllowedIncludes(Options.get("Includes", DefaultAllowedIncludes)), AllowedIncludesGlobList(AllowedIncludes) {} @@ -36,7 +36,7 @@ public: } private: - std::string AllowedIncludes; + StringRef AllowedIncludes; GlobList AllowedIncludesGlobList; }; diff --git a/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp b/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp index 22ff5ce..ef9263b 100644 --- a/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/AmbiguousSmartptrResetCallCheck.cpp @@ -20,12 +20,9 @@ namespace clang::tidy::readability { namespace { AST_MATCHER(CXXMethodDecl, hasOnlyDefaultParameters) { - for (const auto *Param : Node.parameters()) { - if (!Param->hasDefaultArg()) - return false; - } - - return true; + return llvm::all_of(Node.parameters(), [](const ParmVarDecl *Param) { + return Param->hasDefaultArg(); + }); } const auto DefaultSmartPointers = "::std::shared_ptr;::std::unique_ptr;" diff --git a/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDecls.cpp b/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDeclsCheck.cpp index 02fe913..506f8e2 100644 --- a/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDecls.cpp +++ b/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDeclsCheck.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "AvoidConstParamsInDecls.h" +#include "AvoidConstParamsInDeclsCheck.h" #include "../utils/LexerUtils.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -26,8 +26,7 @@ static SourceRange getTypeRange(const ParmVarDecl &Param) { static std::optional<Token> findConstToRemove(const ParmVarDecl &Param, const MatchFinder::MatchResult &Result) { - - CharSourceRange FileRange = Lexer::makeFileCharRange( + const CharSourceRange FileRange = Lexer::makeFileCharRange( CharSourceRange::getTokenRange(getTypeRange(Param)), *Result.SourceManager, Result.Context->getLangOpts()); @@ -38,11 +37,12 @@ findConstToRemove(const ParmVarDecl &Param, tok::kw_const, FileRange, *Result.Context, *Result.SourceManager); } -void AvoidConstParamsInDecls::storeOptions(ClangTidyOptions::OptionMap &Opts) { +void AvoidConstParamsInDeclsCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "IgnoreMacros", IgnoreMacros); } -void AvoidConstParamsInDecls::registerMatchers(MatchFinder *Finder) { +void AvoidConstParamsInDeclsCheck::registerMatchers(MatchFinder *Finder) { const auto ConstParamDecl = parmVarDecl(hasType(qualType(isConstQualified()))).bind("param"); Finder->addMatcher(functionDecl(unless(isDefinition()), @@ -51,7 +51,8 @@ void AvoidConstParamsInDecls::registerMatchers(MatchFinder *Finder) { this); } -void AvoidConstParamsInDecls::check(const MatchFinder::MatchResult &Result) { +void AvoidConstParamsInDeclsCheck::check( + const MatchFinder::MatchResult &Result) { const auto *Func = Result.Nodes.getNodeAs<FunctionDecl>("func"); const auto *Param = Result.Nodes.getNodeAs<ParmVarDecl>("param"); diff --git a/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDecls.h b/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDeclsCheck.h index 6490508..467a9a4 100644 --- a/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDecls.h +++ b/clang-tools-extra/clang-tidy/readability/AvoidConstParamsInDeclsCheck.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOIDCONSTPARAMSINDECLS_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOIDCONSTPARAMSINDECLS_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOIDCONSTPARAMSINDECLSCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOIDCONSTPARAMSINDECLSCHECK_H #include "../ClangTidyCheck.h" @@ -15,9 +15,12 @@ namespace clang::tidy::readability { // Detect function declarations that have const value parameters and discourage // them. -class AvoidConstParamsInDecls : public ClangTidyCheck { +// +// For the user-facing documentation see: +// https://clang.llvm.org/extra/clang-tidy/checks/readability/avoid-const-params-in-decls.html +class AvoidConstParamsInDeclsCheck : public ClangTidyCheck { public: - AvoidConstParamsInDecls(StringRef Name, ClangTidyContext *Context) + AvoidConstParamsInDeclsCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IgnoreMacros(Options.get("IgnoreMacros", true)) {} @@ -34,4 +37,4 @@ private: } // namespace clang::tidy::readability -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOIDCONSTPARAMSINDECLS_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_AVOIDCONSTPARAMSINDECLSCHECK_H diff --git a/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.cpp index 40a4fa1..2b31281 100644 --- a/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.cpp @@ -47,9 +47,9 @@ void AvoidReturnWithVoidValueCheck::check( Result.Nodes.getNodeAs<CompoundStmt>("compound_parent"); if (!StrictMode && !SurroundingBlock) return; - DiagnosticBuilder Diag = diag(VoidReturn->getBeginLoc(), - "return statement within a void function " - "should not have a specified return value"); + const DiagnosticBuilder Diag = diag( + VoidReturn->getBeginLoc(), "return statement within a void function " + "should not have a specified return value"); const SourceLocation SemicolonPos = utils::lexer::findNextTerminator( VoidReturn->getEndLoc(), *Result.SourceManager, getLangOpts()); if (SemicolonPos.isInvalid()) diff --git a/clang-tools-extra/clang-tidy/readability/AvoidUnconditionalPreprocessorIfCheck.cpp b/clang-tools-extra/clang-tidy/readability/AvoidUnconditionalPreprocessorIfCheck.cpp index c53c706..9fc8185 100644 --- a/clang-tools-extra/clang-tidy/readability/AvoidUnconditionalPreprocessorIfCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/AvoidUnconditionalPreprocessorIfCheck.cpp @@ -17,7 +17,6 @@ namespace clang::tidy::readability { namespace { struct AvoidUnconditionalPreprocessorIfPPCallbacks : public PPCallbacks { - explicit AvoidUnconditionalPreprocessorIfPPCallbacks(ClangTidyCheck &Check, Preprocessor &PP) : Check(Check), PP(PP) {} @@ -40,7 +39,7 @@ struct AvoidUnconditionalPreprocessorIfPPCallbacks : public PPCallbacks { bool isImmutable(SourceManager &SM, const LangOptions &LangOpts, SourceRange ConditionRange) { - SourceLocation Loc = ConditionRange.getBegin(); + const SourceLocation Loc = ConditionRange.getBegin(); if (Loc.isMacroID()) return false; diff --git a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp index 1952e14..2b55bb8 100644 --- a/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/BracesAroundStatementsCheck.cpp @@ -20,7 +20,8 @@ namespace clang::tidy::readability { static tok::TokenKind getTokenKind(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts) { Token Tok; - SourceLocation Beginning = Lexer::GetBeginningOfToken(Loc, SM, LangOpts); + const SourceLocation Beginning = + Lexer::GetBeginningOfToken(Loc, SM, LangOpts); const bool Invalid = Lexer::getRawToken(Beginning, Tok, SM, LangOpts); assert(!Invalid && "Expected a valid token."); @@ -38,7 +39,7 @@ forwardSkipWhitespaceAndComments(SourceLocation Loc, const SourceManager &SM, while (isWhitespace(*SM.getCharacterData(Loc))) Loc = Loc.getLocWithOffset(1); - tok::TokenKind TokKind = getTokenKind(Loc, SM, LangOpts); + const tok::TokenKind TokKind = getTokenKind(Loc, SM, LangOpts); if (TokKind != tok::comment) return Loc; @@ -80,7 +81,8 @@ void BracesAroundStatementsCheck::check( } else if (const auto *S = Result.Nodes.getNodeAs<DoStmt>("do")) { checkStmt(Result, S->getBody(), S->getDoLoc(), S->getWhileLoc()); } else if (const auto *S = Result.Nodes.getNodeAs<WhileStmt>("while")) { - SourceLocation StartLoc = findRParenLoc(S, SM, Context->getLangOpts()); + const SourceLocation StartLoc = + findRParenLoc(S, SM, Context->getLangOpts()); if (StartLoc.isInvalid()) return; checkStmt(Result, S->getBody(), StartLoc); @@ -89,12 +91,14 @@ void BracesAroundStatementsCheck::check( if (S->isConsteval()) return; - SourceLocation StartLoc = findRParenLoc(S, SM, Context->getLangOpts()); + const SourceLocation StartLoc = + findRParenLoc(S, SM, Context->getLangOpts()); if (StartLoc.isInvalid()) return; if (ForceBracesStmts.erase(S)) ForceBracesStmts.insert(S->getThen()); - bool BracedIf = checkStmt(Result, S->getThen(), StartLoc, S->getElseLoc()); + const bool BracedIf = + checkStmt(Result, S->getThen(), StartLoc, S->getElseLoc()); const Stmt *Else = S->getElse(); if (Else && BracedIf) ForceBracesStmts.insert(Else); @@ -125,7 +129,7 @@ BracesAroundStatementsCheck::findRParenLoc(const IfOrWhileStmt *S, return {}; } - SourceLocation PastCondEndLoc = + const SourceLocation PastCondEndLoc = Lexer::getLocForEndOfToken(CondEndLoc, 0, SM, LangOpts); if (PastCondEndLoc.isInvalid()) return {}; @@ -133,7 +137,7 @@ BracesAroundStatementsCheck::findRParenLoc(const IfOrWhileStmt *S, forwardSkipWhitespaceAndComments(PastCondEndLoc, SM, LangOpts); if (RParenLoc.isInvalid()) return {}; - tok::TokenKind TokKind = getTokenKind(RParenLoc, SM, LangOpts); + const tok::TokenKind TokKind = getTokenKind(RParenLoc, SM, LangOpts); if (TokKind != tok::r_paren) return {}; return RParenLoc; diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 91e9354..161a0d9 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -5,7 +5,7 @@ set(LLVM_LINK_COMPONENTS add_clang_library(clangTidyReadabilityModule STATIC AmbiguousSmartptrResetCallCheck.cpp - AvoidConstParamsInDecls.cpp + AvoidConstParamsInDeclsCheck.cpp AvoidNestedConditionalOperatorCheck.cpp AvoidReturnWithVoidValueCheck.cpp AvoidUnconditionalPreprocessorIfCheck.cpp @@ -14,7 +14,7 @@ add_clang_library(clangTidyReadabilityModule STATIC ContainerContainsCheck.cpp ContainerDataPointerCheck.cpp ContainerSizeEmptyCheck.cpp - ConvertMemberFunctionsToStatic.cpp + ConvertMemberFunctionsToStaticCheck.cpp DeleteNullPointerCheck.cpp DuplicateIncludeCheck.cpp ElseAfterReturnCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp index 6ccd933..cfdf0e9 100644 --- a/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ConstReturnTypeCheck.cpp @@ -32,13 +32,13 @@ findConstToRemove(const FunctionDecl *Def, // written in the source (for out-of-line declarations). A FunctionDecl's // "location" is the start of its name, so, when the name is unqualified, we // use `getLocation()`. - SourceLocation NameBeginLoc = Def->getQualifier() - ? Def->getQualifierLoc().getBeginLoc() - : Def->getLocation(); + const SourceLocation NameBeginLoc = Def->getQualifier() + ? Def->getQualifierLoc().getBeginLoc() + : Def->getLocation(); // Since either of the locs can be in a macro, use `makeFileCharRange` to be // sure that we have a consistent `CharSourceRange`, located entirely in the // source file. - CharSourceRange FileRange = Lexer::makeFileCharRange( + const CharSourceRange FileRange = Lexer::makeFileCharRange( CharSourceRange::getCharRange(Def->getBeginLoc(), NameBeginLoc), *Result.SourceManager, Result.Context->getLangOpts()); @@ -118,12 +118,12 @@ void ConstReturnTypeCheck::check(const MatchFinder::MatchResult &Result) { (Def->getBeginLoc().isMacroID() || Def->getEndLoc().isMacroID())) return; - CheckResult CR = checkDef(Def, Result); + const CheckResult CR = checkDef(Def, Result); { // Clang only supports one in-flight diagnostic at a time. So, delimit the // scope of `Diagnostic` to allow further diagnostics after the scope. We // use `getInnerLocStart` to get the start of the return type. - DiagnosticBuilder Diagnostic = + const DiagnosticBuilder Diagnostic = diag(Def->getInnerLocStart(), "return type %0 is 'const'-qualified at the top level, which may " "reduce code readability without improving const correctness") diff --git a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp index 850ef86c..efcf13d 100644 --- a/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ContainerContainsCheck.cpp @@ -47,9 +47,8 @@ void ContainerContainsCheck::registerMatchers(MatchFinder *Finder) { const auto StringNpos = anyOf(declRefExpr(to(varDecl(hasName("npos")))), memberExpr(member(hasName("npos")))); - auto AddSimpleMatcher = [&](auto Matcher) { - Finder->addMatcher( - traverse(TK_IgnoreUnlessSpelledInSource, std::move(Matcher)), this); + auto AddSimpleMatcher = [&](const auto &Matcher) { + Finder->addMatcher(traverse(TK_IgnoreUnlessSpelledInSource, Matcher), this); }; // Find membership tests which use `count()`. @@ -110,7 +109,7 @@ void ContainerContainsCheck::check(const MatchFinder::MatchResult &Result) { Result.Nodes.getNodeAs<Expr>("negativeComparison"); assert((!PositiveComparison || !NegativeComparison) && "only one of PositiveComparison or NegativeComparison should be set"); - bool Negated = NegativeComparison != nullptr; + const bool Negated = NegativeComparison != nullptr; const auto *Comparison = Negated ? NegativeComparison : PositiveComparison; const StringRef ContainsFunName = Result.Nodes.getNodeAs<CXXMethodDecl>("contains_fun")->getName(); @@ -121,7 +120,7 @@ void ContainerContainsCheck::check(const MatchFinder::MatchResult &Result) { << ContainsFunName; // Don't fix it if it's in a macro invocation. Leave fixing it to the user. - SourceLocation FuncCallLoc = Comparison->getEndLoc(); + const SourceLocation FuncCallLoc = Comparison->getEndLoc(); if (!FuncCallLoc.isValid() || FuncCallLoc.isMacroID()) return; diff --git a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp index 11756d1..e308aef 100644 --- a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp @@ -101,14 +101,17 @@ void ContainerDataPointerCheck::check(const MatchFinder::MatchResult &Result) { else if (ACE) CE = ACE; - SourceRange SrcRange = CE->getSourceRange(); + const SourceRange SrcRange = CE->getSourceRange(); std::string ReplacementText{ Lexer::getSourceText(CharSourceRange::getTokenRange(SrcRange), *Result.SourceManager, getLangOpts())}; - if (!isa<DeclRefExpr, ArraySubscriptExpr, CXXOperatorCallExpr, CallExpr, - MemberExpr>(CE)) + const auto *OpCall = dyn_cast<CXXOperatorCallExpr>(CE); + const bool NeedsParens = + OpCall ? (OpCall->getOperator() != OO_Subscript) + : !isa<DeclRefExpr, MemberExpr, ArraySubscriptExpr, CallExpr>(CE); + if (NeedsParens) ReplacementText = "(" + ReplacementText + ")"; if (CE->getType()->isPointerType()) @@ -116,7 +119,7 @@ void ContainerDataPointerCheck::check(const MatchFinder::MatchResult &Result) { else ReplacementText += ".data()"; - FixItHint Hint = + const FixItHint Hint = FixItHint::CreateReplacement(UO->getSourceRange(), ReplacementText); diag(UO->getBeginLoc(), "'data' should be used for accessing the data pointer instead of taking " diff --git a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStaticCheck.cpp index 6da4cf7..e6276e3 100644 --- a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp +++ b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStaticCheck.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "ConvertMemberFunctionsToStatic.h" +#include "ConvertMemberFunctionsToStaticCheck.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/RecursiveASTVisitor.h" @@ -78,7 +78,8 @@ AST_MATCHER(CXXMethodDecl, usesThis) { } // namespace -void ConvertMemberFunctionsToStatic::registerMatchers(MatchFinder *Finder) { +void ConvertMemberFunctionsToStaticCheck::registerMatchers( + MatchFinder *Finder) { Finder->addMatcher( cxxMethodDecl( isDefinition(), isUserProvided(), @@ -118,26 +119,26 @@ static SourceRange getLocationOfConst(const TypeSourceInfo *TSI, const auto FTL = TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>(); assert(FTL); - SourceRange Range{FTL.getRParenLoc().getLocWithOffset(1), - FTL.getLocalRangeEnd()}; + const SourceRange Range{FTL.getRParenLoc().getLocWithOffset(1), + FTL.getLocalRangeEnd()}; // Inside Range, there might be other keywords and trailing return types. // Find the exact position of "const". - StringRef Text = getStringFromRange(SourceMgr, LangOpts, Range); - size_t Offset = Text.find("const"); + const StringRef Text = getStringFromRange(SourceMgr, LangOpts, Range); + const size_t Offset = Text.find("const"); if (Offset == StringRef::npos) return {}; - SourceLocation Start = Range.getBegin().getLocWithOffset(Offset); + const SourceLocation Start = Range.getBegin().getLocWithOffset(Offset); return {Start, Start.getLocWithOffset(strlen("const") - 1)}; } -void ConvertMemberFunctionsToStatic::check( +void ConvertMemberFunctionsToStaticCheck::check( const MatchFinder::MatchResult &Result) { const auto *Definition = Result.Nodes.getNodeAs<CXXMethodDecl>("x"); // TODO: For out-of-line declarations, don't modify the source if the header // is excluded by the -header-filter option. - DiagnosticBuilder Diag = + const DiagnosticBuilder Diag = diag(Definition->getLocation(), "method %0 can be made static") << Definition; @@ -152,15 +153,15 @@ void ConvertMemberFunctionsToStatic::check( if (Definition->isConst()) { // Make sure that we either remove 'const' on both declaration and // definition or emit no fix-it at all. - SourceRange DefConst = getLocationOfConst(Definition->getTypeSourceInfo(), - *Result.SourceManager, - Result.Context->getLangOpts()); + const SourceRange DefConst = getLocationOfConst( + Definition->getTypeSourceInfo(), *Result.SourceManager, + Result.Context->getLangOpts()); if (DefConst.isInvalid()) return; if (Declaration != Definition) { - SourceRange DeclConst = getLocationOfConst( + const SourceRange DeclConst = getLocationOfConst( Declaration->getTypeSourceInfo(), *Result.SourceManager, Result.Context->getLangOpts()); diff --git a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.h b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStaticCheck.h index 20cb7f2..4f8a1a9 100644 --- a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.h +++ b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStaticCheck.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMBERFUNCTIONSTOSTATIC_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMBERFUNCTIONSTOSTATIC_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMBERFUNCTIONSTOSTATICCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMBERFUNCTIONSTOSTATICCHECK_H #include "../ClangTidyCheck.h" @@ -18,10 +18,10 @@ namespace clang::tidy::readability { /// /// For the user-facing documentation see: /// https://clang.llvm.org/extra/clang-tidy/checks/ -/// readability-convert-member-functions-to-static.html -class ConvertMemberFunctionsToStatic : public ClangTidyCheck { +/// readability/convert-member-functions-to-static.html +class ConvertMemberFunctionsToStaticCheck : public ClangTidyCheck { public: - ConvertMemberFunctionsToStatic(StringRef Name, ClangTidyContext *Context) + ConvertMemberFunctionsToStaticCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus; @@ -32,4 +32,4 @@ public: } // namespace clang::tidy::readability -#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMBERFUNCTIONSTOSTATIC_H +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONVERTMEMBERFUNCTIONSTOSTATICCHECK_H diff --git a/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.cpp b/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.cpp index 0237c05..4842fe2 100644 --- a/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.cpp @@ -7,10 +7,12 @@ //===----------------------------------------------------------------------===// #include "DuplicateIncludeCheck.h" +#include "../utils/OptionsUtils.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Regex.h" #include <memory> namespace clang::tidy::readability { @@ -33,11 +35,8 @@ using FileList = SmallVector<StringRef>; class DuplicateIncludeCallbacks : public PPCallbacks { public: DuplicateIncludeCallbacks(DuplicateIncludeCheck &Check, - const SourceManager &SM) - : Check(Check), SM(SM) { - // The main file doesn't participate in the FileChanged notification. - Files.emplace_back(); - } + const SourceManager &SM, + llvm::ArrayRef<StringRef> IgnoredList); void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, @@ -62,10 +61,31 @@ private: SmallVector<FileList> Files; DuplicateIncludeCheck &Check; const SourceManager &SM; + SmallVector<llvm::Regex> AllowedRegexes; }; } // namespace +DuplicateIncludeCheck::DuplicateIncludeCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoredFilesList(utils::options::parseStringList( + Options.get("IgnoredFilesList", ""))) {} + +DuplicateIncludeCallbacks::DuplicateIncludeCallbacks( + DuplicateIncludeCheck &Check, const SourceManager &SM, + llvm::ArrayRef<StringRef> IgnoredList) + : Check(Check), SM(SM) { + // The main file doesn't participate in the FileChanged notification. + Files.emplace_back(); + + AllowedRegexes.reserve(IgnoredList.size()); + for (const StringRef &It : IgnoredList) { + if (!It.empty()) + AllowedRegexes.emplace_back(It); + } +} + void DuplicateIncludeCallbacks::FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, @@ -78,7 +98,7 @@ void DuplicateIncludeCallbacks::FileChanged(SourceLocation Loc, void DuplicateIncludeCallbacks::InclusionDirective( SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, - bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, + bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef /*File*/, StringRef SearchPath, StringRef RelativePath, const Module *SuggestedModule, bool ModuleImported, SrcMgr::CharacteristicKind FileType) { // Skip includes behind macros @@ -86,11 +106,15 @@ void DuplicateIncludeCallbacks::InclusionDirective( FilenameRange.getEnd().isMacroID()) return; if (llvm::is_contained(Files.back(), FileName)) { + if (llvm::any_of(AllowedRegexes, [&FileName](const llvm::Regex &R) { + return R.match(FileName); + })) + return; // We want to delete the entire line, so make sure that [Start,End] covers // everything. - SourceLocation Start = + const SourceLocation Start = advanceBeyondCurrentLine(SM, HashLoc, -1).getLocWithOffset(-1); - SourceLocation End = + const SourceLocation End = advanceBeyondCurrentLine(SM, FilenameRange.getEnd(), 1); Check.diag(HashLoc, "duplicate include") << FixItHint::CreateRemoval(SourceRange{Start, End}); @@ -111,7 +135,13 @@ void DuplicateIncludeCallbacks::MacroUndefined(const Token &MacroNameTok, void DuplicateIncludeCheck::registerPPCallbacks( const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { - PP->addPPCallbacks(std::make_unique<DuplicateIncludeCallbacks>(*this, SM)); + PP->addPPCallbacks( + std::make_unique<DuplicateIncludeCallbacks>(*this, SM, IgnoredFilesList)); +} + +void DuplicateIncludeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoredFilesList", + utils::options::serializeStringList(IgnoredFilesList)); } } // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.h b/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.h index ca36791..1ee5b1c 100644 --- a/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.h +++ b/clang-tools-extra/clang-tidy/readability/DuplicateIncludeCheck.h @@ -19,11 +19,16 @@ namespace clang::tidy::readability { /// directives between them are analyzed. class DuplicateIncludeCheck : public ClangTidyCheck { public: - DuplicateIncludeCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + DuplicateIncludeCheck(StringRef Name, ClangTidyContext *Context); void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override; + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + +private: + // Semicolon-separated list of regexes or file names to ignore from duplicate + // warnings. + const std::vector<StringRef> IgnoredFilesList; }; } // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp index 6399e7d9..4ef28c8b 100644 --- a/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp @@ -124,21 +124,21 @@ static void removeElseAndBrackets(DiagnosticBuilder &Diag, ASTContext &Context, if (const auto *CS = dyn_cast<CompoundStmt>(Else)) { Diag << tooling::fixit::createRemoval(ElseLoc); - SourceLocation LBrace = CS->getLBracLoc(); - SourceLocation RBrace = CS->getRBracLoc(); - SourceLocation RangeStart = + const SourceLocation LBrace = CS->getLBracLoc(); + const SourceLocation RBrace = CS->getRBracLoc(); + const SourceLocation RangeStart = Remap(LBrace).getLocWithOffset(TokLen(LBrace) + 1); - SourceLocation RangeEnd = Remap(RBrace).getLocWithOffset(-1); + const SourceLocation RangeEnd = Remap(RBrace).getLocWithOffset(-1); - llvm::StringRef Repl = Lexer::getSourceText( + const llvm::StringRef Repl = Lexer::getSourceText( CharSourceRange::getTokenRange(RangeStart, RangeEnd), Context.getSourceManager(), Context.getLangOpts()); Diag << tooling::fixit::createReplacement(CS->getSourceRange(), Repl); } else { - SourceLocation ElseExpandedLoc = Remap(ElseLoc); - SourceLocation EndLoc = Remap(Else->getEndLoc()); + const SourceLocation ElseExpandedLoc = Remap(ElseLoc); + const SourceLocation EndLoc = Remap(Else->getEndLoc()); - llvm::StringRef Repl = Lexer::getSourceText( + const llvm::StringRef Repl = Lexer::getSourceText( CharSourceRange::getTokenRange( ElseExpandedLoc.getLocWithOffset(TokLen(ElseLoc) + 1), EndLoc), Context.getSourceManager(), Context.getLangOpts()); @@ -185,9 +185,8 @@ void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { static bool hasPreprocessorBranchEndBetweenLocations( const ElseAfterReturnCheck::ConditionalBranchMap &ConditionalBranchMap, const SourceManager &SM, SourceLocation StartLoc, SourceLocation EndLoc) { - - SourceLocation ExpandedStartLoc = SM.getExpansionLoc(StartLoc); - SourceLocation ExpandedEndLoc = SM.getExpansionLoc(EndLoc); + const SourceLocation ExpandedStartLoc = SM.getExpansionLoc(StartLoc); + const SourceLocation ExpandedEndLoc = SM.getExpansionLoc(EndLoc); if (!SM.isWrittenInSameFile(ExpandedStartLoc, ExpandedEndLoc)) return false; @@ -239,14 +238,14 @@ void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) { const auto *Else = Result.Nodes.getNodeAs<Stmt>("else"); const auto *OuterScope = Result.Nodes.getNodeAs<CompoundStmt>("cs"); const auto *Interrupt = Result.Nodes.getNodeAs<Stmt>(InterruptingStr); - SourceLocation ElseLoc = If->getElseLoc(); + const SourceLocation ElseLoc = If->getElseLoc(); if (hasPreprocessorBranchEndBetweenLocations( PPConditionals, *Result.SourceManager, Interrupt->getBeginLoc(), ElseLoc)) return; - bool IsLastInScope = OuterScope->body_back() == If; + const bool IsLastInScope = OuterScope->body_back() == If; const StringRef ControlFlowInterrupter = getControlFlowString(*Interrupt); if (!IsLastInScope && containsDeclInScope(Else)) { @@ -276,7 +275,7 @@ void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) { } const DeclStmt *VDeclStmt = If->getConditionVariableDeclStmt(); const VarDecl *VDecl = If->getConditionVariable(); - std::string Repl = + const std::string Repl = (tooling::fixit::getText(*VDeclStmt, *Result.Context) + llvm::StringRef(";\n") + tooling::fixit::getText(If->getIfLoc(), *Result.Context)) diff --git a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp index a2a5c3e..049ad75 100644 --- a/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/EnumInitialValueCheck.cpp @@ -75,7 +75,7 @@ static void cleanInitialValue(DiagnosticBuilder &Diag, namespace { AST_MATCHER(EnumDecl, isMacro) { - SourceLocation Loc = Node.getBeginLoc(); + const SourceLocation Loc = Node.getBeginLoc(); return Loc.isMacroID(); } @@ -165,7 +165,7 @@ void EnumInitialValueCheck::registerMatchers(MatchFinder *Finder) { void EnumInitialValueCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *Enum = Result.Nodes.getNodeAs<EnumDecl>("inconsistent")) { - DiagnosticBuilder Diag = + const DiagnosticBuilder Diag = diag( Enum->getBeginLoc(), "initial values in enum '%0' are not consistent, consider explicit " diff --git a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp index 4791df0..a966f1f 100644 --- a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp @@ -229,14 +229,14 @@ public: bool traverseStmtWithIncreasedNestingLevel(Stmt *Node) { ++CurrentNestingLevel; - bool ShouldContinue = Base::TraverseStmt(Node); + const bool ShouldContinue = Base::TraverseStmt(Node); --CurrentNestingLevel; return ShouldContinue; } bool traverseDeclWithIncreasedNestingLevel(Decl *Node) { ++CurrentNestingLevel; - bool ShouldContinue = Base::TraverseDecl(Node); + const bool ShouldContinue = Base::TraverseDecl(Node); --CurrentNestingLevel; return ShouldContinue; } @@ -336,7 +336,7 @@ public: // Record the operator that we are currently processing and traverse it. CurrentBinaryOperator = Op->getOpcode(); - bool ShouldContinue = Base::TraverseBinaryOperator(Op); + const bool ShouldContinue = Base::TraverseBinaryOperator(Op); // And restore the previous binary operator, which might be nonexistent. CurrentBinaryOperator = BinOpCopy; @@ -354,7 +354,7 @@ public: // Else, do add [uninitialized] frame to the stack, and traverse call. BinaryOperatorsStack.emplace(); - bool ShouldContinue = Base::TraverseCallExpr(Node); + const bool ShouldContinue = Base::TraverseCallExpr(Node); // And remove the top frame. BinaryOperatorsStack.pop(); @@ -519,7 +519,6 @@ void FunctionCognitiveComplexityCheck::registerMatchers(MatchFinder *Finder) { void FunctionCognitiveComplexityCheck::check( const MatchFinder::MatchResult &Result) { - FunctionASTVisitor Visitor(IgnoreMacros); SourceLocation Loc; @@ -558,7 +557,7 @@ void FunctionCognitiveComplexityCheck::check( // Increase, on the other hand, can be 0. diag(Detail.Loc, Msgs[MsgId], DiagnosticIDs::Note) - << (unsigned)Increase << (unsigned)Detail.Nesting << 1 + Detail.Nesting; + << Increase << Detail.Nesting << 1 + Detail.Nesting; } } diff --git a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp index 8c58346..2f0949c 100644 --- a/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/FunctionSizeCheck.cpp @@ -181,14 +181,14 @@ void FunctionSizeCheck::check(const MatchFinder::MatchResult &Result) { // Count the lines including whitespace and comments. Really simple. if (const Stmt *Body = Func->getBody()) { - SourceManager *SM = Result.SourceManager; + const SourceManager *SM = Result.SourceManager; if (SM->isWrittenInSameFile(Body->getBeginLoc(), Body->getEndLoc())) { FI.Lines = SM->getSpellingLineNumber(Body->getEndLoc()) - SM->getSpellingLineNumber(Body->getBeginLoc()); } } - unsigned ActualNumberParameters = Func->getNumParams(); + const unsigned ActualNumberParameters = Func->getNumParams(); if ((LineThreshold && FI.Lines > LineThreshold) || (StatementThreshold && FI.Statements > StatementThreshold) || diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierLengthCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierLengthCheck.cpp index 877f0a4..a6204de 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierLengthCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierLengthCheck.cpp @@ -91,7 +91,7 @@ void IdentifierLengthCheck::check(const MatchFinder::MatchResult &Result) { if (!StandaloneVar->getIdentifier()) return; - StringRef VarName = StandaloneVar->getName(); + const StringRef VarName = StandaloneVar->getName(); if (VarName.size() >= MinimumVariableNameLength || IgnoredVariableNames.match(VarName)) @@ -106,7 +106,7 @@ void IdentifierLengthCheck::check(const MatchFinder::MatchResult &Result) { if (!ExceptionVarName->getIdentifier()) return; - StringRef VarName = ExceptionVarName->getName(); + const StringRef VarName = ExceptionVarName->getName(); if (VarName.size() >= MinimumExceptionNameLength || IgnoredExceptionVariableNames.match(VarName)) return; @@ -120,7 +120,7 @@ void IdentifierLengthCheck::check(const MatchFinder::MatchResult &Result) { if (!LoopVar->getIdentifier()) return; - StringRef VarName = LoopVar->getName(); + const StringRef VarName = LoopVar->getName(); if (VarName.size() >= MinimumLoopCounterNameLength || IgnoredLoopCounterNames.match(VarName)) @@ -135,7 +135,7 @@ void IdentifierLengthCheck::check(const MatchFinder::MatchResult &Result) { if (!ParamVar->getIdentifier()) return; - StringRef VarName = ParamVar->getName(); + const StringRef VarName = ParamVar->getName(); if (VarName.size() >= MinimumParameterNameLength || IgnoredParameterNames.match(VarName)) diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp index ef3eac8..79f8437 100644 --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -261,7 +261,7 @@ IdentifierNamingCheck::FileStyle IdentifierNamingCheck::getFileStyleFromOptions( Styles.resize(SK_Count); SmallString<64> StyleString; for (unsigned I = 0; I < SK_Count; ++I) { - size_t StyleSize = StyleNames[I].size(); + const size_t StyleSize = StyleNames[I].size(); StyleString.assign({StyleNames[I], "HungarianPrefix"}); auto HPTOpt = @@ -271,13 +271,13 @@ IdentifierNamingCheck::FileStyle IdentifierNamingCheck::getFileStyleFromOptions( memcpy(&StyleString[StyleSize], "IgnoredRegexp", 13); StyleString.truncate(StyleSize + 13); - std::optional<StringRef> IgnoredRegexpStr = Options.get(StyleString); + const std::optional<StringRef> IgnoredRegexpStr = Options.get(StyleString); memcpy(&StyleString[StyleSize], "Prefix", 6); StyleString.truncate(StyleSize + 6); - std::optional<StringRef> Prefix(Options.get(StyleString)); + const std::optional<StringRef> Prefix(Options.get(StyleString)); // Fast replacement of [Pre]fix -> [Suf]fix. memcpy(&StyleString[StyleSize], "Suf", 3); - std::optional<StringRef> Postfix(Options.get(StyleString)); + const std::optional<StringRef> Postfix(Options.get(StyleString)); memcpy(&StyleString[StyleSize], "Case", 4); StyleString.pop_back_n(2); std::optional<CaseType> CaseOptional = @@ -288,8 +288,9 @@ IdentifierNamingCheck::FileStyle IdentifierNamingCheck::getFileStyleFromOptions( Postfix.value_or(""), IgnoredRegexpStr.value_or(""), HPTOpt.value_or(IdentifierNamingCheck::HPT_Off)); } - bool IgnoreMainLike = Options.get("IgnoreMainLikeFunctions", false); - bool CheckAnonFieldInParent = Options.get("CheckAnonFieldInParent", false); + const bool IgnoreMainLike = Options.get("IgnoreMainLikeFunctions", false); + const bool CheckAnonFieldInParent = + Options.get("CheckAnonFieldInParent", false); return {std::move(Styles), std::move(HNOption), IgnoreMainLike, CheckAnonFieldInParent}; } @@ -317,8 +318,8 @@ std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName( if (!EOL) EOL = Begin + strlen(Begin); - const char *PosList[] = {strchr(Begin, '='), strchr(Begin, ';'), - strchr(Begin, ','), strchr(Begin, ')'), EOL}; + const char *const PosList[] = {strchr(Begin, '='), strchr(Begin, ';'), + strchr(Begin, ','), strchr(Begin, ')'), EOL}; for (const auto &Pos : PosList) { if (Pos > Begin) EOL = std::min(EOL, Pos); @@ -340,7 +341,7 @@ std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName( "virtual"}; // Remove keywords - for (StringRef Kw : Keywords) { + for (const StringRef Kw : Keywords) { for (size_t Pos = 0; (Pos = Type.find(Kw, Pos)) != std::string::npos;) { Type.replace(Pos, Kw.size(), ""); } @@ -376,7 +377,7 @@ std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName( " int", " char", " double", " long", " short"}; bool RedundantRemoved = false; for (auto Kw : TailsOfMultiWordType) { - size_t Pos = Type.rfind(Kw); + const size_t Pos = Type.rfind(Kw); if (Pos != std::string::npos) { const size_t PtrCount = getAsteriskCount(Type, ND); Type = Type.substr(0, Pos + Kw.size() + PtrCount); @@ -387,14 +388,14 @@ std::string IdentifierNamingCheck::HungarianNotation::getDeclTypeName( TypeName = Type.erase(0, Type.find_first_not_of(' ')); if (!RedundantRemoved) { - std::size_t FoundSpace = Type.find(' '); + const std::size_t FoundSpace = Type.find(' '); if (FoundSpace != std::string::npos) Type = Type.substr(0, FoundSpace); } TypeName = Type.erase(0, Type.find_first_not_of(' ')); - QualType QT = VD->getType(); + const QualType QT = VD->getType(); if (!QT.isNull() && QT->isArrayType()) TypeName.append("[]"); } @@ -407,7 +408,6 @@ IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name, : RenamerClangTidyCheck(Name, Context), Context(Context), GetConfigPerFile(Options.get("GetConfigPerFile", true)), IgnoreFailedSplit(Options.get("IgnoreFailedSplit", false)) { - auto IterAndInserted = NamingStylesCache.try_emplace( llvm::sys::path::parent_path(Context->getCurrentFile()), getFileStyleFromOptions(Options)); @@ -446,19 +446,18 @@ bool IdentifierNamingCheck::HungarianNotation::isOptionEnabled( void IdentifierNamingCheck::HungarianNotation::loadFileConfig( const ClangTidyCheck::OptionsView &Options, IdentifierNamingCheck::HungarianNotationOption &HNOption) const { - static constexpr StringRef HNOpts[] = {"TreatStructAsClass"}; static constexpr StringRef HNDerivedTypes[] = {"Array", "Pointer", "FunctionPointer"}; - StringRef Section = "HungarianNotation."; + const StringRef Section = "HungarianNotation."; SmallString<128> Buffer = {Section, "General."}; size_t DefSize = Buffer.size(); for (const auto &Opt : HNOpts) { Buffer.truncate(DefSize); Buffer.append(Opt); - StringRef Val = Options.get(Buffer, ""); + const StringRef Val = Options.get(Buffer, ""); if (!Val.empty()) HNOption.General[Opt] = Val.str(); } @@ -468,7 +467,7 @@ void IdentifierNamingCheck::HungarianNotation::loadFileConfig( for (const auto &Type : HNDerivedTypes) { Buffer.truncate(DefSize); Buffer.append(Type); - StringRef Val = Options.get(Buffer, ""); + const StringRef Val = Options.get(Buffer, ""); if (!Val.empty()) HNOption.DerivedType[Type] = Val.str(); } @@ -484,7 +483,7 @@ void IdentifierNamingCheck::HungarianNotation::loadFileConfig( for (const auto &CStr : HNCStrings) { Buffer.truncate(DefSize); Buffer.append(CStr.first); - StringRef Val = Options.get(Buffer, ""); + const StringRef Val = Options.get(Buffer, ""); if (!Val.empty()) HNOption.CString[CStr.second] = Val.str(); } @@ -494,7 +493,7 @@ void IdentifierNamingCheck::HungarianNotation::loadFileConfig( for (const auto &PrimType : HungarianNotationPrimitiveTypes) { Buffer.truncate(DefSize); Buffer.append(PrimType); - StringRef Val = Options.get(Buffer, ""); + const StringRef Val = Options.get(Buffer, ""); if (!Val.empty()) { std::string Type = PrimType.str(); llvm::replace(Type, '-', ' '); @@ -507,7 +506,7 @@ void IdentifierNamingCheck::HungarianNotation::loadFileConfig( for (const auto &Type : HungarianNotationUserDefinedTypes) { Buffer.truncate(DefSize); Buffer.append(Type); - StringRef Val = Options.get(Buffer, ""); + const StringRef Val = Options.get(Buffer, ""); if (!Val.empty()) HNOption.UserDefinedType[Type] = Val.str(); } @@ -528,7 +527,7 @@ std::string IdentifierNamingCheck::HungarianNotation::getPrefix( } else if (const auto *CRD = dyn_cast<CXXRecordDecl>(ND)) { Prefix = getClassPrefix(CRD, HNOption); } else if (isa<VarDecl, FieldDecl, RecordDecl>(ND)) { - std::string TypeName = getDeclTypeName(ND); + const std::string TypeName = getDeclTypeName(ND); if (!TypeName.empty()) Prefix = getDataTypePrefix(TypeName, ND, HNOption); } @@ -542,8 +541,8 @@ bool IdentifierNamingCheck::HungarianNotation::removeDuplicatedPrefix( if (Words.size() <= 1) return true; - std::string CorrectName = Words[0].str(); - std::vector<llvm::StringMap<std::string>> MapList = { + const std::string CorrectName = Words[0].str(); + const std::vector<llvm::StringMap<std::string>> MapList = { HNOption.CString, HNOption.DerivedType, HNOption.PrimitiveType, HNOption.UserDefinedType}; @@ -570,12 +569,12 @@ std::string IdentifierNamingCheck::HungarianNotation::getDataTypePrefix( // Derived types std::string PrefixStr; if (const auto *TD = dyn_cast<ValueDecl>(ND)) { - QualType QT = TD->getType(); + const QualType QT = TD->getType(); if (QT->isFunctionPointerType()) { PrefixStr = HNOption.DerivedType.lookup("FunctionPointer"); } else if (QT->isPointerType()) { for (const auto &CStr : HNOption.CString) { - std::string Key = CStr.getKey().str(); + const std::string Key = CStr.getKey().str(); if (ModifiedTypeName.find(Key) == 0) { PrefixStr = CStr.getValue(); ModifiedTypeName = ModifiedTypeName.substr( @@ -585,7 +584,7 @@ std::string IdentifierNamingCheck::HungarianNotation::getDataTypePrefix( } } else if (QT->isArrayType()) { for (const auto &CStr : HNOption.CString) { - std::string Key = CStr.getKey().str(); + const std::string Key = CStr.getKey().str(); if (ModifiedTypeName.find(Key) == 0) { PrefixStr = CStr.getValue(); break; @@ -594,14 +593,14 @@ std::string IdentifierNamingCheck::HungarianNotation::getDataTypePrefix( if (PrefixStr.empty()) PrefixStr = HNOption.DerivedType.lookup("Array"); } else if (QT->isReferenceType()) { - size_t Pos = ModifiedTypeName.find_last_of('&'); + const size_t Pos = ModifiedTypeName.find_last_of('&'); if (Pos != std::string::npos) ModifiedTypeName = ModifiedTypeName.substr(0, Pos); } } // Pointers - size_t PtrCount = getAsteriskCount(ModifiedTypeName); + const size_t PtrCount = getAsteriskCount(ModifiedTypeName); if (PtrCount > 0) { ModifiedTypeName = [&](std::string Str, StringRef From, StringRef To) { size_t StartPos = 0; @@ -642,7 +641,6 @@ std::string IdentifierNamingCheck::HungarianNotation::getDataTypePrefix( std::string IdentifierNamingCheck::HungarianNotation::getClassPrefix( const CXXRecordDecl *CRD, const IdentifierNamingCheck::HungarianNotationOption &HNOption) const { - if (CRD->isUnion()) return {}; @@ -663,10 +661,10 @@ std::string IdentifierNamingCheck::HungarianNotation::getEnumPrefix( Name = Name.erase(0, Name.find_first_not_of(' ')); } - static llvm::Regex Splitter( + static const llvm::Regex Splitter( "([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$)"); - StringRef EnumName(Name); + const StringRef EnumName(Name); SmallVector<StringRef, 8> Substrs; EnumName.split(Substrs, "_", -1, false); @@ -692,7 +690,7 @@ std::string IdentifierNamingCheck::HungarianNotation::getEnumPrefix( } std::string Initial; - for (StringRef Word : Words) + for (const StringRef Word : Words) Initial += tolower(Word[0]); return Initial; @@ -713,7 +711,7 @@ size_t IdentifierNamingCheck::HungarianNotation::getAsteriskCount( const std::string &TypeName, const NamedDecl *ND) const { size_t PtrCount = 0; if (const auto *TD = dyn_cast<ValueDecl>(ND)) { - QualType QT = TD->getType(); + const QualType QT = TD->getType(); if (QT->isPointerType()) PtrCount = getAsteriskCount(TypeName); } @@ -722,7 +720,6 @@ size_t IdentifierNamingCheck::HungarianNotation::getAsteriskCount( void IdentifierNamingCheck::HungarianNotation::loadDefaultConfig( IdentifierNamingCheck::HungarianNotationOption &HNOption) const { - // Options static constexpr std::pair<StringRef, StringRef> General[] = { {"TreatStructAsClass", "false"}}; @@ -834,11 +831,12 @@ void IdentifierNamingCheck::HungarianNotation::loadDefaultConfig( void IdentifierNamingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { RenamerClangTidyCheck::storeOptions(Opts); SmallString<64> StyleString; - ArrayRef<std::optional<NamingStyle>> Styles = MainFileStyle->getStyles(); + const ArrayRef<std::optional<NamingStyle>> Styles = + MainFileStyle->getStyles(); for (size_t I = 0; I < SK_Count; ++I) { if (!Styles[I]) continue; - size_t StyleSize = StyleNames[I].size(); + const size_t StyleSize = StyleNames[I].size(); StyleString.assign({StyleNames[I], "HungarianPrefix"}); Options.store(Opts, StyleString, Styles[I]->HPType); @@ -871,7 +869,7 @@ bool IdentifierNamingCheck::matchesStyle( const IdentifierNamingCheck::NamingStyle &Style, const IdentifierNamingCheck::HungarianNotationOption &HNOption, const NamedDecl *Decl) const { - static llvm::Regex Matchers[] = { + static const llvm::Regex Matchers[] = { llvm::Regex("^.*$"), llvm::Regex("^[a-z][a-z0-9_]*$"), llvm::Regex("^[a-z][a-zA-Z0-9]*$"), @@ -887,7 +885,7 @@ bool IdentifierNamingCheck::matchesStyle( if (!Name.consume_back(Style.Suffix)) return false; if (IdentifierNamingCheck::HungarianPrefixType::HPT_Off != Style.HPType) { - std::string HNPrefix = HungarianNotation.getPrefix(Decl, HNOption); + const std::string HNPrefix = HungarianNotation.getPrefix(Decl, HNOption); if (!HNPrefix.empty()) { if (!Name.consume_front(HNPrefix)) return false; @@ -914,7 +912,7 @@ std::string IdentifierNamingCheck::fixupWithCase( const IdentifierNamingCheck::NamingStyle &Style, const IdentifierNamingCheck::HungarianNotationOption &HNOption, IdentifierNamingCheck::CaseType Case) const { - static llvm::Regex Splitter( + static const llvm::Regex Splitter( "([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$)"); SmallVector<StringRef, 8> Substrs; @@ -1070,7 +1068,7 @@ bool IdentifierNamingCheck::isParamInMainLikeFunction( return false; if (!IsIntType(FDecl->parameters()[0]->getType())) return false; - MainType Type = IsCharPtrPtr(FDecl->parameters()[1]->getType()); + const MainType Type = IsCharPtrPtr(FDecl->parameters()[1]->getType()); if (Type == None) return false; if (FDecl->getNumParams() == 3 && @@ -1078,13 +1076,14 @@ bool IdentifierNamingCheck::isParamInMainLikeFunction( return false; if (Type == Main) { - static llvm::Regex Matcher( + static const llvm::Regex Matcher( "(^[Mm]ain([_A-Z]|$))|([a-z0-9_]Main([_A-Z]|$))|(_main(_|$))"); assert(Matcher.isValid() && "Invalid Matcher for main like functions."); return Matcher.match(FDecl->getName()); } - static llvm::Regex Matcher("(^((W[Mm])|(wm))ain([_A-Z]|$))|([a-z0-9_]W[Mm]" - "ain([_A-Z]|$))|(_wmain(_|$))"); + static const llvm::Regex Matcher( + "(^((W[Mm])|(wm))ain([_A-Z]|$))|([a-z0-9_]W[Mm]" + "ain([_A-Z]|$))|(_wmain(_|$))"); assert(Matcher.isValid() && "Invalid Matcher for wmain like functions."); return Matcher.match(FDecl->getName()); } @@ -1212,7 +1211,7 @@ StyleKind IdentifierNamingCheck::findStyleKind( if (const auto *Decl = dyn_cast<ParmVarDecl>(D)) { if (isParamInMainLikeFunction(*Decl, IgnoreMainLikeFunctions)) return SK_Invalid; - QualType Type = Decl->getType(); + const QualType Type = Decl->getType(); if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable]) return SK_ConstexprVariable; @@ -1381,7 +1380,7 @@ IdentifierNamingCheck::getDeclFailureInfo(const NamedDecl *Decl, if (Decl->isImplicit()) return std::nullopt; - SourceLocation Loc = Decl->getLocation(); + const SourceLocation Loc = Decl->getLocation(); const FileStyle &FileStyle = getStyleForFile(SM.getFilename(Loc)); if (!FileStyle.isActive()) return std::nullopt; @@ -1398,7 +1397,7 @@ IdentifierNamingCheck::getDeclFailureInfo(const NamedDecl *Decl, std::optional<RenamerClangTidyCheck::FailureInfo> IdentifierNamingCheck::getMacroFailureInfo(const Token &MacroNameTok, const SourceManager &SM) const { - SourceLocation Loc = MacroNameTok.getLocation(); + const SourceLocation Loc = MacroNameTok.getLocation(); const FileStyle &Style = getStyleForFile(SM.getFilename(Loc)); if (!Style.isActive()) return std::nullopt; @@ -1431,13 +1430,13 @@ IdentifierNamingCheck::getStyleForFile(StringRef FileName) const { if (!GetConfigPerFile) return *MainFileStyle; - StringRef RealFileName = getRealFileName(FileName); - StringRef Parent = llvm::sys::path::parent_path(RealFileName); + const StringRef RealFileName = getRealFileName(FileName); + const StringRef Parent = llvm::sys::path::parent_path(RealFileName); auto Iter = NamingStylesCache.find(Parent); if (Iter != NamingStylesCache.end()) return Iter->getValue(); - llvm::StringRef CheckName = getID(); + const llvm::StringRef CheckName = getID(); ClangTidyOptions Options = Context->getOptionsForFile(RealFileName); if (Options.Checks && GlobList(*Options.Checks).contains(CheckName)) { auto It = NamingStylesCache.try_emplace( @@ -1459,7 +1458,7 @@ StyleKind IdentifierNamingCheck::findStyleKindForAnonField( utils::findOutermostIndirectFieldDeclForField(AnonField); assert(IFD && "Found an anonymous record field without an IndirectFieldDecl"); - QualType Type = AnonField->getType(); + const QualType Type = AnonField->getType(); if (const auto *F = dyn_cast<FieldDecl>(IFD->chain().front())) { return findStyleKindForField(F, Type, NamingStyles); diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index 4cf8574..c135b42 100644 --- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -22,8 +22,8 @@ namespace clang::tidy::readability { namespace { AST_MATCHER(Stmt, isMacroExpansion) { - SourceManager &SM = Finder->getASTContext().getSourceManager(); - SourceLocation Loc = Node.getBeginLoc(); + const SourceManager &SM = Finder->getASTContext().getSourceManager(); + const SourceLocation Loc = Node.getBeginLoc(); return SM.isMacroBodyExpansion(Loc) || SM.isMacroArgExpansion(Loc); } @@ -32,9 +32,9 @@ AST_MATCHER(Stmt, isC23) { return Finder->getASTContext().getLangOpts().C23; } // Preserve same name as AST_MATCHER(isNULLMacroExpansion) // NOLINTNEXTLINE(llvm-prefer-static-over-anonymous-namespace) bool isNULLMacroExpansion(const Stmt *Statement, ASTContext &Context) { - SourceManager &SM = Context.getSourceManager(); + const SourceManager &SM = Context.getSourceManager(); const LangOptions &LO = Context.getLangOpts(); - SourceLocation Loc = Statement->getBeginLoc(); + const SourceLocation Loc = Statement->getBeginLoc(); return SM.isMacroBodyExpansion(Loc) && Lexer::getImmediateMacroName(Loc, SM, LO) == "NULL"; } @@ -77,11 +77,11 @@ static void fixGenericExprCastToBool(DiagnosticBuilder &Diag, bool UseUpperCaseLiteralSuffix) { // In case of expressions like (! integer), we should remove the redundant not // operator and use inverted comparison (integer == 0). - bool InvertComparison = + const bool InvertComparison = Parent != nullptr && isUnaryLogicalNotOperator(Parent); if (InvertComparison) { - SourceLocation ParentStartLoc = Parent->getBeginLoc(); - SourceLocation ParentEndLoc = + const SourceLocation ParentStartLoc = Parent->getBeginLoc(); + const SourceLocation ParentEndLoc = cast<UnaryOperator>(Parent)->getSubExpr()->getBeginLoc(); Diag << FixItHint::CreateRemoval( CharSourceRange::getCharRange(ParentStartLoc, ParentEndLoc)); @@ -91,9 +91,9 @@ static void fixGenericExprCastToBool(DiagnosticBuilder &Diag, const Expr *SubExpr = Cast->getSubExpr(); - bool NeedInnerParens = + const bool NeedInnerParens = utils::fixit::areParensNeededForStatement(*SubExpr->IgnoreImpCasts()); - bool NeedOuterParens = + const bool NeedOuterParens = Parent != nullptr && utils::fixit::areParensNeededForStatement(*Parent); std::string StartLocInsertion; @@ -133,7 +133,7 @@ static void fixGenericExprCastToBool(DiagnosticBuilder &Diag, EndLocInsertion += ")"; } - SourceLocation EndLoc = Lexer::getLocForEndOfToken( + const SourceLocation EndLoc = Lexer::getLocForEndOfToken( Cast->getEndLoc(), 0, Context.getSourceManager(), Context.getLangOpts()); Diag << FixItHint::CreateInsertion(EndLoc, EndLocInsertion); } @@ -167,8 +167,8 @@ static StringRef getEquivalentBoolLiteralForExpr(const Expr *Expression, } static bool needsSpacePrefix(SourceLocation Loc, ASTContext &Context) { - SourceRange PrefixRange(Loc.getLocWithOffset(-1), Loc); - StringRef SpaceBeforeStmtStr = Lexer::getSourceText( + const SourceRange PrefixRange(Loc.getLocWithOffset(-1), Loc); + const StringRef SpaceBeforeStmtStr = Lexer::getSourceText( CharSourceRange::getCharRange(PrefixRange), Context.getSourceManager(), Context.getLangOpts(), nullptr); if (SpaceBeforeStmtStr.empty()) @@ -198,7 +198,7 @@ static void fixGenericExprCastFromBool(DiagnosticBuilder &Diag, .str()); if (NeedParens) { - SourceLocation EndLoc = Lexer::getLocForEndOfToken( + const SourceLocation EndLoc = Lexer::getLocForEndOfToken( Cast->getEndLoc(), 0, Context.getSourceManager(), Context.getLangOpts()); @@ -234,7 +234,7 @@ static bool isCastAllowedInCondition(const ImplicitCastExpr *Cast, std::queue<const Stmt *> Q; Q.push(Cast); - TraversalKindScope RAII(Context, TK_AsIs); + const TraversalKindScope RAII(Context, TK_AsIs); while (!Q.empty()) { for (const auto &N : Context.getParents(*Q.front())) { @@ -362,7 +362,6 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) { void ImplicitBoolConversionCheck::check( const MatchFinder::MatchResult &Result) { - if (const auto *CastToBool = Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastToBool")) { const auto *Parent = Result.Nodes.getNodeAs<Stmt>("parentStmt"); @@ -396,7 +395,7 @@ void ImplicitBoolConversionCheck::handleCastToBool(const ImplicitCastExpr *Cast, auto Diag = diag(Cast->getBeginLoc(), "implicit conversion %0 -> 'bool'") << Cast->getSubExpr()->getType(); - StringRef EquivalentLiteral = + const StringRef EquivalentLiteral = getEquivalentBoolLiteralForExpr(Cast->getSubExpr(), Context); if (!EquivalentLiteral.empty()) { Diag << tooling::fixit::createReplacement(*Cast, EquivalentLiteral); @@ -409,14 +408,13 @@ void ImplicitBoolConversionCheck::handleCastToBool(const ImplicitCastExpr *Cast, void ImplicitBoolConversionCheck::handleCastFromBool( const ImplicitCastExpr *Cast, const ImplicitCastExpr *NextImplicitCast, ASTContext &Context) { - QualType DestType = + const QualType DestType = NextImplicitCast ? NextImplicitCast->getType() : Cast->getType(); auto Diag = diag(Cast->getBeginLoc(), "implicit conversion 'bool' -> %0") << DestType; if (const auto *BoolLiteral = dyn_cast<CXXBoolLiteralExpr>(Cast->getSubExpr()->IgnoreParens())) { - const auto EquivalentForBoolLiteral = getEquivalentForBoolLiteral(BoolLiteral, DestType, Context); if (UseUpperCaseLiteralSuffix) diff --git a/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp b/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp index 93580a7..7b27ab9 100644 --- a/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp @@ -107,18 +107,22 @@ findDifferingParamsInDeclaration(const FunctionDecl *ParameterSourceDeclaration, while (SourceParamIt != ParameterSourceDeclaration->param_end() && OtherParamIt != OtherDeclaration->param_end()) { + if ((*SourceParamIt)->isParameterPack() != + (*OtherParamIt)->isParameterPack()) + break; + auto SourceParamName = (*SourceParamIt)->getName(); auto OtherParamName = (*OtherParamIt)->getName(); // FIXME: Provide a way to extract commented out parameter name from comment // next to it. if (!nameMatch(SourceParamName, OtherParamName, Strict)) { - SourceRange OtherParamNameRange = + const SourceRange OtherParamNameRange = DeclarationNameInfo((*OtherParamIt)->getDeclName(), (*OtherParamIt)->getLocation()) .getSourceRange(); - bool GenerateFixItHint = checkIfFixItHintIsApplicable( + const bool GenerateFixItHint = checkIfFixItHintIsApplicable( ParameterSourceDeclaration, *SourceParamIt, OriginalDeclaration); DifferingParams.emplace_back(SourceParamName, OtherParamName, @@ -137,11 +141,11 @@ findInconsistentDeclarations(const FunctionDecl *OriginalDeclaration, const FunctionDecl *ParameterSourceDeclaration, SourceManager &SM, bool Strict) { InconsistentDeclarationsContainer InconsistentDeclarations; - SourceLocation ParameterSourceLocation = + const SourceLocation ParameterSourceLocation = ParameterSourceDeclaration->getLocation(); for (const FunctionDecl *OtherDeclaration : OriginalDeclaration->redecls()) { - SourceLocation OtherLocation = OtherDeclaration->getLocation(); + const SourceLocation OtherLocation = OtherDeclaration->getLocation(); if (OtherLocation != ParameterSourceLocation) { // Skip self. DifferingParamsContainer DifferingParams = findDifferingParamsInDeclaration(ParameterSourceDeclaration, @@ -305,7 +309,7 @@ void InconsistentDeclarationParameterNameCheck::check( const FunctionDecl *ParameterSourceDeclaration = getParameterSourceDeclaration(OriginalDeclaration); - InconsistentDeclarationsContainer InconsistentDeclarations = + const InconsistentDeclarationsContainer InconsistentDeclarations = findInconsistentDeclarations(OriginalDeclaration, ParameterSourceDeclaration, *Result.SourceManager, Strict); @@ -315,7 +319,7 @@ void InconsistentDeclarationParameterNameCheck::check( return; } - SourceLocation StartLoc = OriginalDeclaration->getBeginLoc(); + const SourceLocation StartLoc = OriginalDeclaration->getBeginLoc(); if (StartLoc.isMacroID() && IgnoreMacros) { markRedeclarationsAsVisited(OriginalDeclaration); return; diff --git a/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp index bc5edec..fa5a0b7 100644 --- a/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IsolateDeclarationCheck.cpp @@ -107,7 +107,7 @@ static bool typeIsMemberPointer(const Type *T) { static std::optional<std::vector<SourceRange>> declRanges(const DeclStmt *DS, const SourceManager &SM, const LangOptions &LangOpts) { - std::size_t DeclCount = std::distance(DS->decl_begin(), DS->decl_end()); + const std::size_t DeclCount = std::distance(DS->decl_begin(), DS->decl_end()); if (DeclCount < 2) return std::nullopt; @@ -157,7 +157,7 @@ declRanges(const DeclStmt *DS, const SourceManager &SM, if (Start.isInvalid() || Start.isMacroID()) break; - Token T = getPreviousToken(Start, SM, LangOpts); + const Token T = getPreviousToken(Start, SM, LangOpts); if (T.is(tok::l_paren)) { Start = findPreviousTokenStart(Start, SM, LangOpts); continue; @@ -165,7 +165,7 @@ declRanges(const DeclStmt *DS, const SourceManager &SM, break; } - SourceRange DeclRange(DS->getBeginLoc(), Start); + const SourceRange DeclRange(DS->getBeginLoc(), Start); if (DeclRange.isInvalid() || isMacroID(DeclRange)) return std::nullopt; @@ -183,13 +183,13 @@ declRanges(const DeclStmt *DS, const SourceManager &SM, if (typeIsMemberPointer(CurrentDecl->getType().IgnoreParens().getTypePtr())) return std::nullopt; - SourceLocation DeclEnd = + const SourceLocation DeclEnd = CurrentDecl->hasInit() ? findNextTerminator(CurrentDecl->getInit()->getEndLoc(), SM, LangOpts) : findNextTerminator(CurrentDecl->getEndLoc(), SM, LangOpts); - SourceRange VarNameRange(DeclBegin, DeclEnd); + const SourceRange VarNameRange(DeclBegin, DeclEnd); if (VarNameRange.isInvalid() || isMacroID(VarNameRange)) return std::nullopt; @@ -206,7 +206,7 @@ collectSourceRanges(llvm::ArrayRef<SourceRange> Ranges, const SourceManager &SM, Snippets.reserve(Ranges.size()); for (const auto &Range : Ranges) { - CharSourceRange CharRange = Lexer::getAsCharRange( + const CharSourceRange CharRange = Lexer::getAsCharRange( CharSourceRange::getCharRange(Range.getBegin(), Range.getEnd()), SM, LangOpts); @@ -214,7 +214,7 @@ collectSourceRanges(llvm::ArrayRef<SourceRange> Ranges, const SourceManager &SM, return std::nullopt; bool InvalidText = false; - StringRef Snippet = + const StringRef Snippet = Lexer::getSourceText(CharRange, SM, LangOpts, &InvalidText); if (InvalidText) @@ -262,7 +262,7 @@ void IsolateDeclarationCheck::check(const MatchFinder::MatchResult &Result) { return; std::vector<std::string> NewDecls = createIsolatedDecls(*PotentialSnippets); - std::string Replacement = llvm::join( + const std::string Replacement = llvm::join( NewDecls, (Twine("\n") + Lexer::getIndentationForLine(WholeDecl->getBeginLoc(), *Result.SourceManager)) diff --git a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp index a38f7bc..6ba1408 100644 --- a/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MagicNumbersCheck.cpp @@ -25,7 +25,6 @@ namespace clang { static bool isUsedToInitializeAConstant(const MatchFinder::MatchResult &Result, const DynTypedNode &Node) { - const auto *AsDecl = Node.get<DeclaratorDecl>(); if (AsDecl) { if (AsDecl->getType().isConstQualified()) @@ -45,7 +44,6 @@ static bool isUsedToInitializeAConstant(const MatchFinder::MatchResult &Result, static bool isUsedToDefineATypeAlias(const MatchFinder::MatchResult &Result, const DynTypedNode &Node) { - if (Node.get<TypeAliasDecl>() || Node.get<TypedefNameDecl>()) return true; @@ -144,8 +142,7 @@ void MagicNumbersCheck::registerMatchers(MatchFinder *Finder) { } void MagicNumbersCheck::check(const MatchFinder::MatchResult &Result) { - - TraversalKindScope RAII(*Result.Context, TK_AsIs); + const TraversalKindScope RAII(*Result.Context, TK_AsIs); checkBoundMatch<IntegerLiteral>(Result, "integer"); checkBoundMatch<FloatingLiteral>(Result, "float"); @@ -248,7 +245,7 @@ bool MagicNumbersCheck::isBitFieldWidth( bool MagicNumbersCheck::isUserDefinedLiteral( const clang::ast_matchers::MatchFinder::MatchResult &Result, const clang::Expr &Literal) const { - DynTypedNodeList Parents = Result.Context->getParents(Literal); + const DynTypedNodeList Parents = Result.Context->getParents(Literal); if (Parents.empty()) return false; return Parents[0].get<UserDefinedLiteral>() != nullptr; diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp index bea6888..ddc92ef 100644 --- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp @@ -59,7 +59,7 @@ public: UsageKind Usage = Unused; template <class T> const T *getParent(const Expr *E) { - DynTypedNodeList Parents = Ctxt.getParents(*E); + const DynTypedNodeList Parents = Ctxt.getParents(*E); if (Parents.size() != 1) return nullptr; @@ -241,7 +241,7 @@ void MakeMemberFunctionConstCheck::registerMatchers(MatchFinder *Finder) { } static SourceLocation getConstInsertionPoint(const CXXMethodDecl *M) { - TypeSourceInfo *TSI = M->getTypeSourceInfo(); + const TypeSourceInfo *TSI = M->getTypeSourceInfo(); if (!TSI) return {}; diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp index e15b2ec..69bc554 100644 --- a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -56,8 +56,8 @@ static void addParentheses(const BinaryOperator *BinOp, if (!BinOp) return; - int Precedence1 = getPrecedence(BinOp); - int Precedence2 = getPrecedence(ParentBinOp); + const int Precedence1 = getPrecedence(BinOp); + const int Precedence2 = getPrecedence(ParentBinOp); if (ParentBinOp != nullptr && Precedence1 != Precedence2 && Precedence1 > 0 && Precedence2 > 0) { diff --git a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp index 0765d8d..450961c 100644 --- a/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MisleadingIndentationCheck.cpp @@ -21,7 +21,7 @@ static const IfStmt *getPrecedingIf(const SourceManager &SM, if (Parents.size() != 1) return nullptr; if (const auto *PrecedingIf = Parents[0].get<IfStmt>()) { - SourceLocation PreviousElseLoc = PrecedingIf->getElseLoc(); + const SourceLocation PreviousElseLoc = PrecedingIf->getElseLoc(); if (SM.getExpansionLineNumber(PreviousElseLoc) == SM.getExpansionLineNumber(If->getIfLoc())) return PrecedingIf; @@ -33,7 +33,7 @@ void MisleadingIndentationCheck::danglingElseCheck(const SourceManager &SM, ASTContext *Context, const IfStmt *If) { SourceLocation IfLoc = If->getIfLoc(); - SourceLocation ElseLoc = If->getElseLoc(); + const SourceLocation ElseLoc = If->getElseLoc(); if (IfLoc.isMacroID() || ElseLoc.isMacroID()) return; @@ -89,8 +89,8 @@ void MisleadingIndentationCheck::missingBracesCheck( if (isa<CompoundStmt>(Inner)) continue; - SourceLocation InnerLoc = Inner->getBeginLoc(); - SourceLocation OuterLoc = CurrentStmt->getBeginLoc(); + const SourceLocation InnerLoc = Inner->getBeginLoc(); + const SourceLocation OuterLoc = CurrentStmt->getBeginLoc(); if (InnerLoc.isInvalid() || InnerLoc.isMacroID() || OuterLoc.isInvalid() || OuterLoc.isMacroID()) @@ -101,7 +101,7 @@ void MisleadingIndentationCheck::missingBracesCheck( continue; const Stmt *NextStmt = CStmt->body_begin()[I + 1]; - SourceLocation NextLoc = NextStmt->getBeginLoc(); + const SourceLocation NextLoc = NextStmt->getBeginLoc(); if (NextLoc.isInvalid() || NextLoc.isMacroID()) continue; diff --git a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp index 7251d63..1283632 100644 --- a/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NamedParameterCheck.cpp @@ -79,7 +79,7 @@ void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) { // void foo(int /*unused*/) const char *Begin = SM.getCharacterData(Parm->getBeginLoc()); const char *End = SM.getCharacterData(Parm->getLocation()); - StringRef Data(Begin, End - Begin); + const StringRef Data(Begin, End - Begin); if (Data.contains("/*")) continue; @@ -104,7 +104,7 @@ void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) { if (M && M->size_overridden_methods() > 0) { const ParmVarDecl *OtherParm = (*M->begin_overridden_methods())->getParamDecl(P.second); - StringRef Name = OtherParm->getName(); + const StringRef Name = OtherParm->getName(); if (!Name.empty()) NewName = Name; } @@ -112,7 +112,7 @@ void NamedParameterCheck::check(const MatchFinder::MatchResult &Result) { // If the definition has a named parameter use that name. if (Definition) { const ParmVarDecl *DefParm = Definition->getParamDecl(P.second); - StringRef Name = DefParm->getName(); + const StringRef Name = DefParm->getName(); if (!Name.empty()) NewName = Name; } diff --git a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp index 744d23a..dffd7fd 100644 --- a/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NamespaceCommentCheck.cpp @@ -70,7 +70,7 @@ getNamespaceNameAsWritten(SourceLocation &Loc, const SourceManager &Sources, --Nesting; } else if (Nesting == 0) { if (T->is(tok::raw_identifier)) { - StringRef ID = T->getRawIdentifier(); + const StringRef ID = T->getRawIdentifier(); if (ID != "namespace") Result.append(std::string(ID)); if (ID == "inline") @@ -96,13 +96,13 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) { // Don't require closing comments for namespaces spanning less than certain // number of lines. - unsigned StartLine = Sources.getSpellingLineNumber(ND->getBeginLoc()); - unsigned EndLine = Sources.getSpellingLineNumber(ND->getRBraceLoc()); + const unsigned StartLine = Sources.getSpellingLineNumber(ND->getBeginLoc()); + const unsigned EndLine = Sources.getSpellingLineNumber(ND->getRBraceLoc()); if (EndLine - StartLine + 1 <= ShortNamespaceLines) return; // Find next token after the namespace closing brace. - SourceLocation AfterRBrace = Lexer::getLocForEndOfToken( + const SourceLocation AfterRBrace = Lexer::getLocForEndOfToken( ND->getRBraceLoc(), /*Offset=*/0, Sources, getLangOpts()); SourceLocation Loc = AfterRBrace; SourceLocation LBraceLoc = ND->getBeginLoc(); @@ -137,7 +137,8 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) { if (!locationsInSameFile(Sources, ND->getRBraceLoc(), Loc)) return; - bool NextTokenIsOnSameLine = Sources.getSpellingLineNumber(Loc) == EndLine; + const bool NextTokenIsOnSameLine = + Sources.getSpellingLineNumber(Loc) == EndLine; // If we insert a line comment before the token in the same line, we need // to insert a line break. bool NeedLineBreak = NextTokenIsOnSameLine && Tok.isNot(tok::eof); @@ -148,11 +149,12 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) { // Try to find existing namespace closing comment on the same line. if (Tok.is(tok::comment) && NextTokenIsOnSameLine) { - StringRef Comment(Sources.getCharacterData(Loc), Tok.getLength()); + const StringRef Comment(Sources.getCharacterData(Loc), Tok.getLength()); SmallVector<StringRef, 7> Groups; if (NamespaceCommentPattern.match(Comment, &Groups)) { - StringRef NamespaceNameInComment = Groups.size() > 5 ? Groups[5] : ""; - StringRef Anonymous = Groups.size() > 3 ? Groups[3] : ""; + const StringRef NamespaceNameInComment = + Groups.size() > 5 ? Groups[5] : ""; + const StringRef Anonymous = Groups.size() > 3 ? Groups[3] : ""; if ((ND->isAnonymousNamespace() && NamespaceNameInComment.empty()) || (*NamespaceNameAsWritten == NamespaceNameInComment && @@ -186,7 +188,7 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) { // multi-line or there may be other tokens behind it. } - std::string NamespaceNameForDiag = + const std::string NamespaceNameForDiag = ND->isAnonymousNamespace() ? "anonymous namespace" : ("namespace '" + *NamespaceNameAsWritten + "'"); @@ -203,7 +205,7 @@ void NamespaceCommentCheck::check(const MatchFinder::MatchResult &Result) { Fix.append("\n"); // Place diagnostic at an old comment, or closing brace if we did not have it. - SourceLocation DiagLoc = + const SourceLocation DiagLoc = OldCommentRange.getBegin() != OldCommentRange.getEnd() ? OldCommentRange.getBegin() : ND->getRBraceLoc(); diff --git a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp index 29fff39..9fbe3ba 100644 --- a/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/NonConstParameterCheck.cpp @@ -155,7 +155,7 @@ void NonConstParameterCheck::diagnoseNonConstParameters() { dyn_cast_or_null<const FunctionDecl>(Par->getParentFunctionOrMethod()); if (!Function) continue; - unsigned Index = Par->getFunctionScopeIndex(); + const unsigned Index = Par->getFunctionScopeIndex(); for (FunctionDecl *FnDecl : Function->redecls()) { if (FnDecl->getNumParams() <= Index) continue; diff --git a/clang-tools-extra/clang-tidy/readability/OperatorsRepresentationCheck.cpp b/clang-tools-extra/clang-tidy/readability/OperatorsRepresentationCheck.cpp index 196fb31..05f31c7 100644 --- a/clang-tools-extra/clang-tidy/readability/OperatorsRepresentationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/OperatorsRepresentationCheck.cpp @@ -23,7 +23,7 @@ static StringRef getOperatorSpelling(SourceLocation Loc, ASTContext &Context) { if (Loc.isInvalid()) return {}; - SourceManager &SM = Context.getSourceManager(); + const SourceManager &SM = Context.getSourceManager(); Loc = SM.getSpellingLoc(Loc); if (Loc.isInvalid()) @@ -41,7 +41,7 @@ AST_MATCHER_P2(BinaryOperator, hasInvalidBinaryOperatorRepresentation, if (Node.getOpcode() != Kind || ExpectedRepresentation.empty()) return false; - StringRef Spelling = + const StringRef Spelling = getOperatorSpelling(Node.getOperatorLoc(), Finder->getASTContext()); return !Spelling.empty() && Spelling != ExpectedRepresentation; } @@ -52,7 +52,7 @@ AST_MATCHER_P2(UnaryOperator, hasInvalidUnaryOperatorRepresentation, if (Node.getOpcode() != Kind || ExpectedRepresentation.empty()) return false; - StringRef Spelling = + const StringRef Spelling = getOperatorSpelling(Node.getOperatorLoc(), Finder->getASTContext()); return !Spelling.empty() && Spelling != ExpectedRepresentation; } @@ -63,7 +63,7 @@ AST_MATCHER_P2(CXXOperatorCallExpr, hasInvalidOverloadedOperatorRepresentation, if (Node.getOperator() != Kind || ExpectedRepresentation.empty()) return false; - StringRef Spelling = + const StringRef Spelling = getOperatorSpelling(Node.getOperatorLoc(), Finder->getASTContext()); return !Spelling.empty() && Spelling != ExpectedRepresentation; } @@ -136,11 +136,9 @@ getRepresentation(const std::vector<llvm::StringRef> &Config, template <typename T> static bool isAnyOperatorEnabled(const std::vector<llvm::StringRef> &Config, const T &Operators) { - for (const auto &[traditional, alternative] : Operators) { - if (!getRepresentation(Config, traditional, alternative).empty()) - return true; - } - return false; + return llvm::any_of(Operators, [&](const auto &Op) { + return !getRepresentation(Config, Op.first, Op.second).empty(); + }); } OperatorsRepresentationCheck::OperatorsRepresentationCheck( @@ -275,7 +273,6 @@ void OperatorsRepresentationCheck::registerMatchers(MatchFinder *Finder) { void OperatorsRepresentationCheck::check( const MatchFinder::MatchResult &Result) { - SourceLocation Loc; if (const auto *Op = Result.Nodes.getNodeAs<BinaryOperator>("binary_op")) @@ -297,9 +294,9 @@ void OperatorsRepresentationCheck::check( if (TokenRange.isInvalid()) return; - StringRef Spelling = Lexer::getSourceText(TokenRange, *Result.SourceManager, - Result.Context->getLangOpts()); - StringRef TranslatedSpelling = translate(Spelling); + const StringRef Spelling = Lexer::getSourceText( + TokenRange, *Result.SourceManager, Result.Context->getLangOpts()); + const StringRef TranslatedSpelling = translate(Spelling); if (TranslatedSpelling.empty()) return; @@ -312,7 +309,7 @@ void OperatorsRepresentationCheck::check( SourceRepresentation = "a traditional"; TargetRepresentation = "an alternative"; - StringRef SpellingEx = Lexer::getSourceText( + const StringRef SpellingEx = Lexer::getSourceText( CharSourceRange::getCharRange( TokenRange.getBegin().getLocWithOffset(-1), TokenRange.getBegin().getLocWithOffset(Spelling.size() + 1U)), diff --git a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp index 942a0a8..556f7fe 100644 --- a/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/QualifiedAutoCheck.cpp @@ -44,18 +44,18 @@ findQualToken(const VarDecl *Decl, Qualifier Qual, SourceLocation BeginLoc = Decl->getQualifierLoc().getBeginLoc(); if (BeginLoc.isInvalid()) BeginLoc = Decl->getBeginLoc(); - SourceLocation EndLoc = Decl->getLocation(); + const SourceLocation EndLoc = Decl->getLocation(); - CharSourceRange FileRange = Lexer::makeFileCharRange( + const CharSourceRange FileRange = Lexer::makeFileCharRange( CharSourceRange::getCharRange(BeginLoc, EndLoc), *Result.SourceManager, Result.Context->getLangOpts()); if (FileRange.isInvalid()) return std::nullopt; - tok::TokenKind Tok = Qual == Qualifier::Const ? tok::kw_const - : Qual == Qualifier::Volatile ? tok::kw_volatile - : tok::kw_restrict; + const tok::TokenKind Tok = Qual == Qualifier::Const ? tok::kw_const + : Qual == Qualifier::Volatile ? tok::kw_volatile + : tok::kw_restrict; return utils::lexer::getQualifyingToken(Tok, FileRange, *Result.Context, *Result.SourceManager); @@ -90,13 +90,13 @@ mergeReplacementRange(SourceRange &TypeSpecifier, const Token &ConstToken) { } static bool isPointerConst(QualType QType) { - QualType Pointee = QType->getPointeeType(); + const QualType Pointee = QType->getPointeeType(); assert(!Pointee.isNull() && "can't have a null Pointee"); return Pointee.isConstQualified(); } static bool isAutoPointerConst(QualType QType) { - QualType Pointee = + const QualType Pointee = cast<AutoType>(QType->getPointeeType().getTypePtr())->desugar(); assert(!Pointee.isNull() && "can't have a null Pointee"); return Pointee.isConstQualified(); @@ -146,7 +146,6 @@ void QualifiedAutoCheck::registerMatchers(MatchFinder *Finder) { return qualType(anyOf(qualType(pointerType(pointee(InnerMatchers...))), qualType(substTemplateTypeParmType(hasReplacementType( pointerType(pointee(InnerMatchers...))))))); - }; auto IsAutoDeducedToPointer = @@ -223,33 +222,34 @@ void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) { if (Var->getLocation() == TypeSpecifier.getEnd().getLocWithOffset(1)) TypeSpecifier.setEnd(TypeSpecifier.getEnd().getLocWithOffset(1)); - CharSourceRange FixItRange = CharSourceRange::getCharRange(TypeSpecifier); + const CharSourceRange FixItRange = + CharSourceRange::getCharRange(TypeSpecifier); if (FixItRange.isInvalid()) return; SourceLocation FixitLoc = FixItRange.getBegin(); - for (SourceRange &Range : RemoveQualifiersRange) { + for (const SourceRange &Range : RemoveQualifiersRange) { if (Range.getBegin() < FixitLoc) FixitLoc = Range.getBegin(); } - std::string ReplStr = [&] { - llvm::StringRef PtrConst = isPointerConst(Var->getType()) ? "const " : ""; - llvm::StringRef LocalConst = IsLocalConst ? "const " : ""; - llvm::StringRef LocalVol = IsLocalVolatile ? "volatile " : ""; - llvm::StringRef LocalRestrict = IsLocalRestrict ? "__restrict " : ""; + const std::string ReplStr = [&] { + const StringRef PtrConst = isPointerConst(Var->getType()) ? "const " : ""; + const StringRef LocalConst = IsLocalConst ? "const " : ""; + const StringRef LocalVol = IsLocalVolatile ? "volatile " : ""; + const StringRef LocalRestrict = IsLocalRestrict ? "__restrict " : ""; return (PtrConst + "auto *" + LocalConst + LocalVol + LocalRestrict) .str(); }(); - DiagnosticBuilder Diag = + const DiagnosticBuilder Diag = diag(FixitLoc, "'%select{|const }0%select{|volatile }1%select{|__restrict }2auto " "%3' can be declared as '%4%3'") << IsLocalConst << IsLocalVolatile << IsLocalRestrict << Var->getName() << ReplStr; - for (SourceRange &Range : RemoveQualifiersRange) { + for (const SourceRange &Range : RemoveQualifiersRange) { Diag << FixItHint::CreateRemoval(CharSourceRange::getCharRange(Range)); } @@ -286,7 +286,7 @@ void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) { if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() || TypeSpec->getEnd().isMacroID()) return; - SourceLocation InsertPos = TypeSpec->getBegin(); + const SourceLocation InsertPos = TypeSpec->getBegin(); diag(InsertPos, "'auto *%select{|const }0%select{|volatile }1%2' can be declared as " "'const auto *%select{|const }0%select{|volatile }1%2'") @@ -308,7 +308,7 @@ void QualifiedAutoCheck::check(const MatchFinder::MatchResult &Result) { if (TypeSpec->isInvalid() || TypeSpec->getBegin().isMacroID() || TypeSpec->getEnd().isMacroID()) return; - SourceLocation InsertPos = TypeSpec->getBegin(); + const SourceLocation InsertPos = TypeSpec->getBegin(); diag(InsertPos, "'auto &%0' can be declared as 'const auto &%0'") << Var->getName() << FixItHint::CreateInsertion(InsertPos, "const "); } diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index 569302e..afb6357 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -10,7 +10,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "AmbiguousSmartptrResetCallCheck.h" -#include "AvoidConstParamsInDecls.h" +#include "AvoidConstParamsInDeclsCheck.h" #include "AvoidNestedConditionalOperatorCheck.h" #include "AvoidReturnWithVoidValueCheck.h" #include "AvoidUnconditionalPreprocessorIfCheck.h" @@ -19,7 +19,7 @@ #include "ContainerContainsCheck.h" #include "ContainerDataPointerCheck.h" #include "ContainerSizeEmptyCheck.h" -#include "ConvertMemberFunctionsToStatic.h" +#include "ConvertMemberFunctionsToStaticCheck.h" #include "DeleteNullPointerCheck.h" #include "DuplicateIncludeCheck.h" #include "ElseAfterReturnCheck.h" @@ -74,7 +74,7 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck<AmbiguousSmartptrResetCallCheck>( "readability-ambiguous-smartptr-reset-call"); - CheckFactories.registerCheck<AvoidConstParamsInDecls>( + CheckFactories.registerCheck<AvoidConstParamsInDeclsCheck>( "readability-avoid-const-params-in-decls"); CheckFactories.registerCheck<AvoidNestedConditionalOperatorCheck>( "readability-avoid-nested-conditional-operator"); @@ -92,7 +92,7 @@ public: "readability-container-data-pointer"); CheckFactories.registerCheck<ContainerSizeEmptyCheck>( "readability-container-size-empty"); - CheckFactories.registerCheck<ConvertMemberFunctionsToStatic>( + CheckFactories.registerCheck<ConvertMemberFunctionsToStaticCheck>( "readability-convert-member-functions-to-static"); CheckFactories.registerCheck<DeleteNullPointerCheck>( "readability-delete-null-pointer"); diff --git a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp index e93aa16..14580a6 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.cpp @@ -43,7 +43,7 @@ void RedundantAccessSpecifiersCheck::check( LastASDecl = ASDecl; if (CheckFirstDeclaration) { - AccessSpecifier DefaultSpecifier = + const AccessSpecifier DefaultSpecifier = MatchedDecl->isClass() ? AS_private : AS_public; if (ASDecl->getAccess() == DefaultSpecifier) { diag(ASDecl->getLocation(), diff --git a/clang-tools-extra/clang-tidy/readability/RedundantCastingCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantCastingCheck.cpp index 1ee7522..21f481a 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantCastingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantCastingCheck.cpp @@ -9,6 +9,7 @@ #include "RedundantCastingCheck.h" #include "../utils/FixItHintUtils.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/TypeBase.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" @@ -25,11 +26,11 @@ static bool areTypesEqual(QualType S, QualType D) { if (TS != TD) return false; - QualType PtrS = S->getPointeeType(); - QualType PtrD = D->getPointeeType(); + const QualType PtrS = S->getPointeeType(); + const QualType PtrD = D->getPointeeType(); if (!PtrS.isNull() && !PtrD.isNull()) - return areTypesEqual(PtrS, PtrD); + return areTypesEqual(PtrS.IgnoreParens(), PtrD.IgnoreParens()); const DeducedType *DT = S->getContainedDeducedType(); if (DT && DT->isDeduced()) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp index b3b84e2..132b7dd 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantControlFlowCheck.cpp @@ -50,7 +50,7 @@ void RedundantControlFlowCheck::check(const MatchFinder::MatchResult &Result) { void RedundantControlFlowCheck::checkRedundantReturn( const MatchFinder::MatchResult &Result, const CompoundStmt *Block) { - CompoundStmt::const_reverse_body_iterator Last = Block->body_rbegin(); + const CompoundStmt::const_reverse_body_iterator Last = Block->body_rbegin(); if (const auto *Return = dyn_cast<ReturnStmt>(*Last)) issueDiagnostic(Result, Block, Return->getSourceRange(), RedundantReturnDiag); @@ -58,7 +58,7 @@ void RedundantControlFlowCheck::checkRedundantReturn( void RedundantControlFlowCheck::checkRedundantContinue( const MatchFinder::MatchResult &Result, const CompoundStmt *Block) { - CompoundStmt::const_reverse_body_iterator Last = Block->body_rbegin(); + const CompoundStmt::const_reverse_body_iterator Last = Block->body_rbegin(); if (const auto *Continue = dyn_cast<ContinueStmt>(*Last)) issueDiagnostic(Result, Block, Continue->getSourceRange(), RedundantContinueDiag); @@ -67,11 +67,12 @@ void RedundantControlFlowCheck::checkRedundantContinue( void RedundantControlFlowCheck::issueDiagnostic( const MatchFinder::MatchResult &Result, const CompoundStmt *const Block, const SourceRange &StmtRange, const char *const Diag) { - SourceManager &SM = *Result.SourceManager; + const SourceManager &SM = *Result.SourceManager; if (isLocationInMacroExpansion(SM, StmtRange.getBegin())) return; - CompoundStmt::const_reverse_body_iterator Previous = ++Block->body_rbegin(); + const CompoundStmt::const_reverse_body_iterator Previous = + ++Block->body_rbegin(); SourceLocation Start; if (Previous != Block->body_rend()) Start = Lexer::findLocationAfterToken( diff --git a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp index cf6e92d..0f12b8b 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp @@ -79,7 +79,7 @@ void RedundantDeclarationCheck::check(const MatchFinder::MatchResult &Result) { } } - SourceLocation EndLoc = Lexer::getLocForEndOfToken( + const SourceLocation EndLoc = Lexer::getLocForEndOfToken( D->getSourceRange().getEnd(), 0, SM, Result.Context->getLangOpts()); { auto Diag = diag(D->getLocation(), "redundant %0 declaration") << D; diff --git a/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp index 2053b89..7b6eb34 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantInlineSpecifierCheck.cpp @@ -16,10 +16,9 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" #include "clang/Lex/Token.h" -#include "../utils/LexerUtils.h" - using namespace clang::ast_matchers; namespace clang::tidy::readability { @@ -52,7 +51,7 @@ AST_POLYMORPHIC_MATCHER_P(isInternalLinkage, static SourceLocation getInlineTokenLocation(SourceRange RangeLocation, const SourceManager &Sources, const LangOptions &LangOpts) { - SourceLocation Loc = RangeLocation.getBegin(); + const SourceLocation Loc = RangeLocation.getBegin(); if (Loc.isMacroID()) return {}; @@ -106,7 +105,7 @@ template <typename T> void RedundantInlineSpecifierCheck::handleMatchedDecl( const T *MatchedDecl, const SourceManager &Sources, const MatchFinder::MatchResult &Result, StringRef Message) { - SourceLocation Loc = getInlineTokenLocation( + const SourceLocation Loc = getInlineTokenLocation( MatchedDecl->getSourceRange(), Sources, Result.Context->getLangOpts()); if (Loc.isValid()) diag(Loc, Message) << MatchedDecl << FixItHint::CreateRemoval(Loc); diff --git a/clang-tools-extra/clang-tidy/readability/RedundantPreprocessorCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantPreprocessorCheck.cpp index 931126a154..4c50371 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantPreprocessorCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantPreprocessorCheck.cpp @@ -36,7 +36,7 @@ public: void If(SourceLocation Loc, SourceRange ConditionRange, ConditionValueKind ConditionValue) override { - StringRef Condition = + const StringRef Condition = Lexer::getSourceText(CharSourceRange::getTokenRange(ConditionRange), PP.getSourceManager(), PP.getLangOpts()); checkMacroRedundancy(Loc, Condition, IfStack, DK_If, DK_If, true); @@ -44,7 +44,7 @@ public: void Ifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MacroDefinition) override { - std::string MacroName = PP.getSpelling(MacroNameTok); + const std::string MacroName = PP.getSpelling(MacroNameTok); checkMacroRedundancy(Loc, MacroName, IfdefStack, DK_Ifdef, DK_Ifdef, true); checkMacroRedundancy(Loc, MacroName, IfndefStack, DK_Ifdef, DK_Ifndef, false); @@ -52,7 +52,7 @@ public: void Ifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MacroDefinition) override { - std::string MacroName = PP.getSpelling(MacroNameTok); + const std::string MacroName = PP.getSpelling(MacroNameTok); checkMacroRedundancy(Loc, MacroName, IfndefStack, DK_Ifndef, DK_Ifndef, true); checkMacroRedundancy(Loc, MacroName, IfdefStack, DK_Ifndef, DK_Ifdef, diff --git a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp index 1106523..a458ae3 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp @@ -149,8 +149,9 @@ void RedundantSmartptrGetCheck::check(const MatchFinder::MatchResult &Result) { if (!allReturnTypesMatch(Result)) return; - bool IsPtrToPtr = Result.Nodes.getNodeAs<Decl>("ptr_to_ptr") != nullptr; - bool IsMemberExpr = Result.Nodes.getNodeAs<Expr>("memberExpr") != nullptr; + const bool IsPtrToPtr = Result.Nodes.getNodeAs<Decl>("ptr_to_ptr") != nullptr; + const bool IsMemberExpr = + Result.Nodes.getNodeAs<Expr>("memberExpr") != nullptr; const auto *GetCall = Result.Nodes.getNodeAs<Expr>("redundant_get"); if (GetCall->getBeginLoc().isMacroID() && IgnoreMacros) return; @@ -178,7 +179,8 @@ void RedundantSmartptrGetCheck::check(const MatchFinder::MatchResult &Result) { SmartptrText = SmartptrText.drop_back(2); } // Replace foo->get() with *foo, and foo.get() with foo. - std::string Replacement = Twine(IsPtrToPtr ? "*" : "", SmartptrText).str(); + const std::string Replacement = + Twine(IsPtrToPtr ? "*" : "", SmartptrText).str(); diag(GetCall->getBeginLoc(), "redundant get() call on smart pointer") << FixItHint::CreateReplacement(SR, Replacement); } diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp index c90d152..e4d08cb 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp @@ -171,10 +171,10 @@ void RedundantStringCStrCheck::check(const MatchFinder::MatchResult &Result) { const auto *Call = Result.Nodes.getNodeAs<CallExpr>("call"); const auto *Arg = Result.Nodes.getNodeAs<Expr>("arg"); const auto *Member = Result.Nodes.getNodeAs<MemberExpr>("member"); - bool Arrow = Member->isArrow(); + const bool Arrow = Member->isArrow(); // Replace the "call" node with the "arg" node, prefixed with '*' // if the call was using '->' rather than '.'. - std::string ArgText = + const std::string ArgText = Arrow ? utils::fixit::formatDereference(*Arg, *Result.Context) : tooling::fixit::getText(*Arg, *Result.Context).str(); if (ArgText.empty()) diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp index b579aaf..5cbbbca 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp @@ -7,13 +7,11 @@ //===----------------------------------------------------------------------===// #include "RedundantStringInitCheck.h" -#include "../utils/Matchers.h" #include "../utils/OptionsUtils.h" #include "clang/ASTMatchers/ASTMatchers.h" #include <optional> using namespace clang::ast_matchers; -using namespace clang::tidy::matchers; namespace clang::tidy::readability { @@ -23,8 +21,8 @@ const char DefaultStringNames[] = static std::vector<StringRef> removeNamespaces(ArrayRef<StringRef> Names) { std::vector<StringRef> Result; Result.reserve(Names.size()); - for (StringRef Name : Names) { - StringRef::size_type ColonPos = Name.rfind(':'); + for (const StringRef Name : Names) { + const StringRef::size_type ColonPos = Name.rfind(':'); Result.push_back( Name.drop_front(ColonPos == StringRef::npos ? 0 : ColonPos + 1)); } @@ -125,14 +123,14 @@ void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *VDecl = Result.Nodes.getNodeAs<VarDecl>("vardecl")) { // VarDecl's getSourceRange() spans 'string foo = ""' or 'string bar("")'. // So start at getLocation() to span just 'foo = ""' or 'bar("")'. - SourceRange ReplaceRange(VDecl->getLocation(), VDecl->getEndLoc()); + const SourceRange ReplaceRange(VDecl->getLocation(), VDecl->getEndLoc()); diag(VDecl->getLocation(), "redundant string initialization") << FixItHint::CreateReplacement(ReplaceRange, VDecl->getName()); } if (const auto *FDecl = Result.Nodes.getNodeAs<FieldDecl>("fieldDecl")) { // FieldDecl's getSourceRange() spans 'string foo = ""'. // So start at getLocation() to span just 'foo = ""'. - SourceRange ReplaceRange(FDecl->getLocation(), FDecl->getEndLoc()); + const SourceRange ReplaceRange(FDecl->getLocation(), FDecl->getEndLoc()); diag(FDecl->getLocation(), "redundant string initialization") << FixItHint::CreateReplacement(ReplaceRange, FDecl->getName()); } diff --git a/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp index a4edd2b..5f2519c 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantTypenameCheck.cpp @@ -47,6 +47,9 @@ void RedundantTypenameCheck::check(const MatchFinder::MatchResult &Result) { const SourceLocation ElaboratedKeywordLoc = [&] { if (const auto *NonDependentTypeLoc = Result.Nodes.getNodeAs<TypeLoc>("nonDependentTypeLoc")) { + if (NonDependentTypeLoc->getType()->isDependentType()) + return SourceLocation(); + if (const auto TL = NonDependentTypeLoc->getAs<TypedefTypeLoc>()) return TL.getElaboratedKeywordLoc(); @@ -59,8 +62,7 @@ void RedundantTypenameCheck::check(const MatchFinder::MatchResult &Result) { if (const auto TL = NonDependentTypeLoc->getAs<TemplateSpecializationTypeLoc>()) - if (!TL.getType()->isDependentType()) - return TL.getElaboratedKeywordLoc(); + return TL.getElaboratedKeywordLoc(); } else { TypeLoc InnermostTypeLoc = *Result.Nodes.getNodeAs<TypeLoc>("dependentTypeLoc"); diff --git a/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp b/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp index 5d3fd14..398bee1 100644 --- a/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp @@ -37,7 +37,7 @@ struct NotExtendedByDeclBoundToPredicate { AST_MATCHER_P(MaterializeTemporaryExpr, isExtendedByDeclBoundTo, StringRef, ID) { - NotExtendedByDeclBoundToPredicate Predicate{ + const NotExtendedByDeclBoundToPredicate Predicate{ ID, ::clang::DynTypedNode::create(Node)}; return Builder->removeBindings(Predicate); } diff --git a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp index 9f3f26b..1a9c161 100644 --- a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.cpp @@ -203,7 +203,7 @@ static std::string replacementExpression(const ASTContext &Context, .str(), NeedsStaticCast)); - StringRef Text = getText(Context, *E); + const StringRef Text = getText(Context, *E); if (!NeedsStaticCast && needsParensAfterUnaryNegation(E)) return ("!(" + Text + ")").str(); @@ -366,7 +366,7 @@ public: * if (false) ThenStmt(); -> <Empty>; * if (false) ThenStmt(); else ElseStmt() -> ElseStmt(); */ - Expr *Cond = If->getCond()->IgnoreImplicit(); + const Expr *Cond = If->getCond()->IgnoreImplicit(); if (std::optional<bool> Bool = getAsBoolLiteral(Cond, true)) { if (*Bool) Check->replaceWithThenStatement(Context, If, Cond); @@ -379,9 +379,9 @@ public: * if (Cond) return true; else return false; -> return Cond; * if (Cond) return false; else return true; -> return !Cond; */ - if (ExprAndBool ThenReturnBool = + if (const ExprAndBool ThenReturnBool = checkSingleStatement(If->getThen(), parseReturnLiteralBool)) { - ExprAndBool ElseReturnBool = + const ExprAndBool ElseReturnBool = checkSingleStatement(If->getElse(), parseReturnLiteralBool); if (ElseReturnBool && ThenReturnBool.Bool != ElseReturnBool.Bool) { if (Check->ChainedConditionalReturn || @@ -418,9 +418,9 @@ public: return {ME->getMemberDecl(), *RightasBool}; return {}; }; - if (DeclAndBool ThenAssignment = + if (const DeclAndBool ThenAssignment = checkSingleStatement(If->getThen(), VarBoolAssignmentMatcher)) { - DeclAndBool ElseAssignment = + const DeclAndBool ElseAssignment = checkSingleStatement(If->getElse(), VarBoolAssignmentMatcher); if (ElseAssignment.Item == ThenAssignment.Item && ElseAssignment.Bool != ThenAssignment.Bool) { @@ -461,7 +461,7 @@ public: Second != End; ++Second, ++First) { PrevIf = CurIf; CurIf = isa<IfStmt>(*First); - ExprAndBool TrailingReturnBool = parseReturnLiteralBool(*Second); + const ExprAndBool TrailingReturnBool = parseReturnLiteralBool(*Second); if (!TrailingReturnBool) continue; @@ -473,7 +473,7 @@ public: auto *If = cast<IfStmt>(*First); if (!If->hasInitStorage() && !If->hasVarStorage() && !If->isConsteval()) { - ExprAndBool ThenReturnBool = + const ExprAndBool ThenReturnBool = checkSingleStatement(If->getThen(), parseReturnLiteralBool); if (ThenReturnBool && ThenReturnBool.Bool != TrailingReturnBool.Bool) { @@ -497,7 +497,7 @@ public: auto *SubIf = dyn_cast<IfStmt>(SubStmt); if (SubIf && !SubIf->getElse() && !SubIf->hasInitStorage() && !SubIf->hasVarStorage() && !SubIf->isConsteval()) { - ExprAndBool ThenReturnBool = + const ExprAndBool ThenReturnBool = checkSingleStatement(SubIf->getThen(), parseReturnLiteralBool); if (ThenReturnBool && ThenReturnBool.Bool != TrailingReturnBool.Bool) { @@ -574,7 +574,7 @@ public: if (Check->reportDeMorgan(Context, Op, BinaryOp, !IsProcessing, parent(), Parens) && !Check->areDiagsSelfContained()) { - llvm::SaveAndRestore RAII(IsProcessing, true); + const llvm::SaveAndRestore RAII(IsProcessing, true); return Base::TraverseUnaryOperator(Op); } } @@ -638,13 +638,13 @@ void SimplifyBooleanExprCheck::reportBinOp(const ASTContext &Context, if (!isa<CXXBoolLiteralExpr>(Other) && containsBoolLiteral(Other)) return; - bool BoolValue = Bool->getValue(); + const bool BoolValue = Bool->getValue(); auto ReplaceWithExpression = [this, &Context, LHS, RHS, Bool](const Expr *ReplaceWith, bool Negated) { - std::string Replacement = + const std::string Replacement = replacementExpression(Context, Negated, ReplaceWith); - SourceRange Range(LHS->getBeginLoc(), RHS->getEndLoc()); + const SourceRange Range(LHS->getBeginLoc(), RHS->getEndLoc()); issueDiag(Context, Bool->getBeginLoc(), SimplifyOperatorDiagnostic, Range, Replacement); }; @@ -706,11 +706,11 @@ bool SimplifyBooleanExprCheck::issueDiag(const ASTContext &Context, StringRef Description, SourceRange ReplacementRange, StringRef Replacement) { - CharSourceRange CharRange = + const CharSourceRange CharRange = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(ReplacementRange), Context.getSourceManager(), getLangOpts()); - DiagnosticBuilder Diag = diag(Loc, Description); + const DiagnosticBuilder Diag = diag(Loc, Description); const bool HasReplacement = !containsDiscardedTokens(Context, CharRange); if (HasReplacement) Diag << FixItHint::CreateReplacement(CharRange, Replacement); @@ -737,7 +737,7 @@ void SimplifyBooleanExprCheck::replaceWithElseStatement( void SimplifyBooleanExprCheck::replaceWithCondition( const ASTContext &Context, const ConditionalOperator *Ternary, bool Negated) { - std::string Replacement = + const std::string Replacement = replacementExpression(Context, Negated, Ternary->getCond()); issueDiag(Context, Ternary->getTrueExpr()->getBeginLoc(), "redundant boolean literal in ternary expression result", @@ -747,11 +747,11 @@ void SimplifyBooleanExprCheck::replaceWithCondition( void SimplifyBooleanExprCheck::replaceWithReturnCondition( const ASTContext &Context, const IfStmt *If, const Expr *BoolLiteral, bool Negated) { - StringRef Terminator = isa<CompoundStmt>(If->getElse()) ? ";" : ""; - std::string Condition = + const StringRef Terminator = isa<CompoundStmt>(If->getElse()) ? ";" : ""; + const std::string Condition = replacementExpression(Context, Negated, If->getCond()); - std::string Replacement = ("return " + Condition + Terminator).str(); - SourceLocation Start = BoolLiteral->getBeginLoc(); + const std::string Replacement = ("return " + Condition + Terminator).str(); + const SourceLocation Start = BoolLiteral->getBeginLoc(); const bool HasReplacement = issueDiag(Context, Start, SimplifyConditionalReturnDiagnostic, @@ -795,12 +795,13 @@ void SimplifyBooleanExprCheck::replaceWithAssignment(const ASTContext &Context, const Expr *Var, SourceLocation Loc, bool Negated) { - SourceRange Range = IfAssign->getSourceRange(); - StringRef VariableName = getText(Context, *Var); - StringRef Terminator = isa<CompoundStmt>(IfAssign->getElse()) ? ";" : ""; - std::string Condition = + const SourceRange Range = IfAssign->getSourceRange(); + const StringRef VariableName = getText(Context, *Var); + const StringRef Terminator = + isa<CompoundStmt>(IfAssign->getElse()) ? ";" : ""; + const std::string Condition = replacementExpression(Context, Negated, IfAssign->getCond()); - std::string Replacement = + const std::string Replacement = (VariableName + " = " + Condition + Terminator).str(); issueDiag(Context, Loc, "redundant boolean literal in conditional assignment", Range, Replacement); diff --git a/clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp index e9a2eae..abc9f67 100644 --- a/clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp @@ -45,8 +45,8 @@ void StaticDefinitionInAnonymousNamespaceCheck::check( while (Loc < Def->getSourceRange().getEnd() && !Lexer::getRawToken(Loc, Tok, *Result.SourceManager, getLangOpts(), true)) { - SourceRange TokenRange(Tok.getLocation(), Tok.getEndLoc()); - StringRef SourceText = + const SourceRange TokenRange(Tok.getLocation(), Tok.getEndLoc()); + const StringRef SourceText = Lexer::getSourceText(CharSourceRange::getTokenRange(TokenRange), *Result.SourceManager, getLangOpts()); if (SourceText == "static") { diff --git a/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp b/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp index feb248d..0b52a96 100644 --- a/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp @@ -150,8 +150,8 @@ static bool applyAbbreviationHeuristic( /// Check whether the shorter String is a prefix of the longer String. static bool applyPrefixHeuristic(StringRef Arg, StringRef Param, int8_t Threshold) { - StringRef Shorter = Arg.size() < Param.size() ? Arg : Param; - StringRef Longer = Arg.size() >= Param.size() ? Arg : Param; + const StringRef Shorter = Arg.size() < Param.size() ? Arg : Param; + const StringRef Longer = Arg.size() >= Param.size() ? Arg : Param; if (Longer.starts_with_insensitive(Shorter)) return percentage(Shorter.size(), Longer.size()) > Threshold; @@ -162,8 +162,8 @@ static bool applyPrefixHeuristic(StringRef Arg, StringRef Param, /// Check whether the shorter String is a suffix of the longer String. static bool applySuffixHeuristic(StringRef Arg, StringRef Param, int8_t Threshold) { - StringRef Shorter = Arg.size() < Param.size() ? Arg : Param; - StringRef Longer = Arg.size() >= Param.size() ? Arg : Param; + const StringRef Shorter = Arg.size() < Param.size() ? Arg : Param; + const StringRef Longer = Arg.size() >= Param.size() ? Arg : Param; if (Longer.ends_with_insensitive(Shorter)) return percentage(Shorter.size(), Longer.size()) > Threshold; @@ -173,7 +173,6 @@ static bool applySuffixHeuristic(StringRef Arg, StringRef Param, static bool applySubstringHeuristic(StringRef Arg, StringRef Param, int8_t Threshold) { - std::size_t MaxLength = 0; SmallVector<std::size_t, SmallVectorSize> Current(Param.size()); SmallVector<std::size_t, SmallVectorSize> Previous(Param.size()); @@ -196,13 +195,13 @@ static bool applySubstringHeuristic(StringRef Arg, StringRef Param, Current.swap(Previous); } - size_t LongerLength = std::max(Arg.size(), Param.size()); + const size_t LongerLength = std::max(Arg.size(), Param.size()); return percentage(MaxLength, LongerLength) > Threshold; } static bool applyLevenshteinHeuristic(StringRef Arg, StringRef Param, int8_t Threshold) { - std::size_t LongerLength = std::max(Arg.size(), Param.size()); + const std::size_t LongerLength = std::max(Arg.size(), Param.size()); double Dist = Arg.edit_distance(Param); Dist = (1.0 - Dist / LongerLength) * 100.0; return Dist > Threshold; @@ -212,11 +211,11 @@ static bool applyLevenshteinHeuristic(StringRef Arg, StringRef Param, static bool applyJaroWinklerHeuristic(StringRef Arg, StringRef Param, int8_t Threshold) { std::size_t Match = 0, Transpos = 0; - std::ptrdiff_t ArgLen = Arg.size(); - std::ptrdiff_t ParamLen = Param.size(); + const std::ptrdiff_t ArgLen = Arg.size(); + const std::ptrdiff_t ParamLen = Param.size(); SmallVector<int, SmallVectorSize> ArgFlags(ArgLen); SmallVector<int, SmallVectorSize> ParamFlags(ParamLen); - std::ptrdiff_t Range = + const std::ptrdiff_t Range = std::max(std::ptrdiff_t{0}, (std::max(ArgLen, ParamLen) / 2) - 1); // Calculate matching characters. @@ -252,7 +251,7 @@ static bool applyJaroWinklerHeuristic(StringRef Arg, StringRef Param, Transpos /= 2; // Jaro distance. - double MatchD = Match; + const double MatchD = Match; double Dist = ((MatchD / ArgLen) + (MatchD / ParamLen) + ((MatchD - Transpos) / Match)) / 3.0; @@ -347,7 +346,7 @@ static bool arePointersStillQualCompatible(QualType ArgType, QualType ParamType, // The types are compatible, if the parameter is at least as qualified as the // argument, and if it is more qualified, it has to be const on upper pointer // levels. - bool AreTypesQualCompatible = + const bool AreTypesQualCompatible = ParamType.isAtLeastAsQualifiedAs(ArgType, Ctx) && (!ParamType.hasQualifiers() || IsParamContinuouslyConst); // Check whether the parameter's constness continues at the current pointer @@ -401,7 +400,7 @@ static bool areTypesCompatible(QualType ArgType, QualType ParamType, if (!areRefAndQualCompatible(ArgType, ParamType, Ctx)) return false; - bool IsParamReference = ParamType->isReferenceType(); + const bool IsParamReference = ParamType->isReferenceType(); // Reference-ness has already been checked and should be removed // before further checking. @@ -438,7 +437,7 @@ static bool areTypesCompatible(QualType ArgType, QualType ParamType, if (IsParamReference && ParamType->isArrayType()) return isCompatibleWithArrayReference(ArgType, ParamType, Ctx); - bool IsParamContinuouslyConst = + const bool IsParamContinuouslyConst = !IsParamReference || ParamType.getNonReferenceType().isConstQualified(); // Remove the first level of indirection. @@ -513,9 +512,9 @@ SuspiciousCallArgumentCheck::SuspiciousCallArgumentCheck( SmallString<32> Key = HeuristicToString[Idx]; Key.append(BK == BoundKind::DissimilarBelow ? "DissimilarBelow" : "SimilarAbove"); - int8_t Default = BK == BoundKind::DissimilarBelow - ? Defaults[Idx].DissimilarBelow - : Defaults[Idx].SimilarAbove; + const int8_t Default = BK == BoundKind::DissimilarBelow + ? Defaults[Idx].DissimilarBelow + : Defaults[Idx].SimilarAbove; return Options.get(Key, Default); }; for (std::size_t Idx = 0; Idx < HeuristicCount; ++Idx) { @@ -527,7 +526,7 @@ SuspiciousCallArgumentCheck::SuspiciousCallArgumentCheck( GetBoundOpt(H, BoundKind::SimilarAbove))); } - for (StringRef Abbreviation : optutils::parseStringList( + for (const StringRef Abbreviation : optutils::parseStringList( Options.get("Abbreviations", DefaultAbbreviations))) { auto KeyAndValue = Abbreviation.split("="); assert(!KeyAndValue.first.empty() && !KeyAndValue.second.empty()); @@ -652,7 +651,7 @@ void SuspiciousCallArgumentCheck::check( if (ArgNames.empty()) return; - std::size_t ParamCount = ParamNames.size(); + const std::size_t ParamCount = ParamNames.size(); // Check similarity. for (std::size_t I = 0; I < ParamCount; ++I) { @@ -673,9 +672,9 @@ void SuspiciousCallArgumentCheck::check( << MatchedCallExpr->getArg(J)->getSourceRange(); // Note at the functions declaration. - SourceLocation IParNameLoc = + const SourceLocation IParNameLoc = CalleeFuncDecl->getParamDecl(I)->getLocation(); - SourceLocation JParNameLoc = + const SourceLocation JParNameLoc = CalleeFuncDecl->getParamDecl(J)->getLocation(); diag(CalleeFuncDecl->getLocation(), "in the call to %0, declared here", @@ -697,7 +696,7 @@ void SuspiciousCallArgumentCheck::setParamNamesAndTypes( for (const ParmVarDecl *Param : CalleeFuncDecl->parameters()) { ParamTypes.push_back(Param->getType()); - if (IdentifierInfo *II = Param->getIdentifier()) + if (const IdentifierInfo *II = Param->getIdentifier()) ParamNames.push_back(II->getName()); else ParamNames.push_back(StringRef()); @@ -759,24 +758,22 @@ bool SuspiciousCallArgumentCheck::areParamAndArgComparable( bool SuspiciousCallArgumentCheck::areArgsSwapped(std::size_t Position1, std::size_t Position2) const { - for (Heuristic H : AppliedHeuristics) { - bool A1ToP2Similar = areNamesSimilar( + return llvm::any_of(AppliedHeuristics, [&](Heuristic H) { + const bool A1ToP2Similar = areNamesSimilar( ArgNames[Position2], ParamNames[Position1], H, BoundKind::SimilarAbove); - bool A2ToP1Similar = areNamesSimilar( + const bool A2ToP1Similar = areNamesSimilar( ArgNames[Position1], ParamNames[Position2], H, BoundKind::SimilarAbove); - bool A1ToP1Dissimilar = + const bool A1ToP1Dissimilar = !areNamesSimilar(ArgNames[Position1], ParamNames[Position1], H, BoundKind::DissimilarBelow); - bool A2ToP2Dissimilar = + const bool A2ToP2Dissimilar = !areNamesSimilar(ArgNames[Position2], ParamNames[Position2], H, BoundKind::DissimilarBelow); - if ((A1ToP2Similar || A2ToP1Similar) && A1ToP1Dissimilar && - A2ToP2Dissimilar) - return true; - } - return false; + return (A1ToP2Similar || A2ToP1Similar) && A1ToP1Dissimilar && + A2ToP2Dissimilar; + }); } bool SuspiciousCallArgumentCheck::areNamesSimilar(StringRef Arg, diff --git a/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp b/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp index c9d7041..1dff8089 100644 --- a/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp @@ -28,7 +28,6 @@ UniqueptrDeleteReleaseCheck::UniqueptrDeleteReleaseCheck( PreferResetCall(Options.get("PreferResetCall", false)) {} void UniqueptrDeleteReleaseCheck::registerMatchers(MatchFinder *Finder) { - auto UniquePtrWithDefaultDelete = classTemplateSpecializationDecl( hasName("::std::unique_ptr"), hasTemplateArgument(1, refersToType(hasDeclaration(cxxRecordDecl( diff --git a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp index 740a68d..db226f9 100644 --- a/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp @@ -110,7 +110,7 @@ shouldReplaceLiteralSuffix(const Expr &Literal, ReplacementDsc.LiteralLocation = L.getSourceRange(); // Was this literal fully spelled or is it a product of macro expansion? - bool RangeCanBeFixed = + const bool RangeCanBeFixed = utils::rangeCanBeFixed(ReplacementDsc.LiteralLocation, &SM); // The literal may have macro expansion, we need the final expanded src range. diff --git a/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.cpp index 82eb6de..6364915 100644 --- a/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.cpp @@ -20,7 +20,7 @@ namespace { /// followed by a Stmt matching the inner matcher. AST_MATCHER_P(Stmt, nextStmt, ast_matchers::internal::Matcher<Stmt>, InnerMatcher) { - DynTypedNodeList Parents = Finder->getASTContext().getParents(Node); + const DynTypedNodeList Parents = Finder->getASTContext().getParents(Node); if (Parents.size() != 1) return false; @@ -71,7 +71,6 @@ void UseAnyOfAllOfCheck::registerMatchers(MatchFinder *Finder) { } static bool isViableLoop(const CXXForRangeStmt &S, ASTContext &Context) { - ExprMutationAnalyzer Mutations(*S.getBody(), Context); if (Mutations.isMutated(S.getLoopVariable())) return false; @@ -86,7 +85,6 @@ static bool isViableLoop(const CXXForRangeStmt &S, ASTContext &Context) { } void UseAnyOfAllOfCheck::check(const MatchFinder::MatchResult &Result) { - if (const auto *S = Result.Nodes.getNodeAs<CXXForRangeStmt>("any_of_loop")) { if (!isViableLoop(*S, *Result.Context)) return; diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp index 8052e04..ee0810b 100644 --- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp @@ -77,11 +77,11 @@ static QualType getNonTemplateAlias(QualType QT) { static QualType getReplacementCastType(const Expr *CondLhs, const Expr *CondRhs, QualType ComparedType) { - QualType LhsType = CondLhs->getType(); - QualType RhsType = CondRhs->getType(); - QualType LhsCanonicalType = + const QualType LhsType = CondLhs->getType(); + const QualType RhsType = CondRhs->getType(); + const QualType LhsCanonicalType = LhsType.getCanonicalType().getNonReferenceType().getUnqualifiedType(); - QualType RhsCanonicalType = + const QualType RhsCanonicalType = RhsType.getCanonicalType().getNonReferenceType().getUnqualifiedType(); QualType GlobalImplicitCastType; if (LhsCanonicalType != RhsCanonicalType) { @@ -96,12 +96,11 @@ static QualType getReplacementCastType(const Expr *CondLhs, const Expr *CondRhs, return GlobalImplicitCastType; } -static std::string createReplacement(const Expr *CondLhs, const Expr *CondRhs, - const Expr *AssignLhs, - const SourceManager &Source, - const LangOptions &LO, - StringRef FunctionName, - const BinaryOperator *BO) { +static std::string +createReplacement(const Expr *CondLhs, const Expr *CondRhs, + const Expr *AssignLhs, const SourceManager &Source, + const LangOptions &LO, StringRef FunctionName, + const BinaryOperator *BO, StringRef Comment = "") { const llvm::StringRef CondLhsStr = Lexer::getSourceText( Source.getExpansionRange(CondLhs->getSourceRange()), Source, LO); const llvm::StringRef CondRhsStr = Lexer::getSourceText( @@ -109,14 +108,15 @@ static std::string createReplacement(const Expr *CondLhs, const Expr *CondRhs, const llvm::StringRef AssignLhsStr = Lexer::getSourceText( Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO); - QualType GlobalImplicitCastType = + const QualType GlobalImplicitCastType = getReplacementCastType(CondLhs, CondRhs, BO->getLHS()->getType()); return (AssignLhsStr + " = " + FunctionName + (!GlobalImplicitCastType.isNull() ? "<" + GlobalImplicitCastType.getAsString() + ">(" : "(") + - CondLhsStr + ", " + CondRhsStr + ");") + CondLhsStr + ", " + CondRhsStr + ");" + (Comment.empty() ? "" : " ") + + Comment) .str(); } @@ -172,13 +172,65 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) { auto ReplaceAndDiagnose = [&](const llvm::StringRef FunctionName) { const SourceManager &Source = *Result.SourceManager; + llvm::SmallString<64> Comment; + + const auto AppendNormalized = [&](llvm::StringRef Text) { + Text = Text.ltrim(); + if (!Text.empty()) { + if (!Comment.empty()) + Comment += " "; + Comment += Text; + } + }; + + const auto GetSourceText = [&](SourceLocation StartLoc, + SourceLocation EndLoc) { + return Lexer::getSourceText( + CharSourceRange::getCharRange( + Lexer::getLocForEndOfToken(StartLoc, 0, Source, LO), EndLoc), + Source, LO); + }; + + // Captures: + // if (cond) // Comment A + // if (cond) /* Comment A */ { ... } + // if (cond) /* Comment A */ x = y; + AppendNormalized( + GetSourceText(If->getRParenLoc(), If->getThen()->getBeginLoc())); + + if (const auto *CS = dyn_cast<CompoundStmt>(If->getThen())) { + const Stmt *Inner = CS->body_front(); + + // Captures: + // if (cond) { // Comment B + // ... + // } + // if (cond) { /* Comment B */ x = y; } + AppendNormalized(GetSourceText(CS->getBeginLoc(), Inner->getBeginLoc())); + + // Captures: + // if (cond) { x = y; // Comment C } + // if (cond) { x = y; /* Comment C */ } + llvm::StringRef PostInner = + GetSourceText(Inner->getEndLoc(), CS->getEndLoc()); + + // Strip the trailing semicolon to avoid fixes like: + // x = std::min(x, y);; // comment + const size_t Semi = PostInner.find(';'); + if (Semi != llvm::StringRef::npos && + PostInner.take_front(Semi).trim().empty()) { + PostInner = PostInner.drop_front(Semi + 1); + } + AppendNormalized(PostInner); + } + diag(IfLocation, "use `%0` instead of `%1`") << FunctionName << BinaryOp->getOpcodeStr() << FixItHint::CreateReplacement( SourceRange(IfLocation, Lexer::getLocForEndOfToken( ThenLocation, 0, Source, LO)), createReplacement(CondLhs, CondRhs, AssignLhs, Source, LO, - FunctionName, BinaryOp)) + FunctionName, BinaryOp, Comment)) << IncludeInserter.createIncludeInsertion( Source.getFileID(If->getBeginLoc()), AlgorithmHeader); }; diff --git a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp index f5e4bf0..6a1f61d 100644 --- a/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tools-extra/clang-tidy/tool/ClangTidyMain.cpp @@ -104,8 +104,7 @@ Configuration files: )"); const char DefaultChecks[] = // Enable these checks by default: - "clang-diagnostic-*," // * compiler diagnostics - "clang-analyzer-*"; // * Static Analyzer checks + "clang-diagnostic-*"; // * compiler diagnostics static cl::opt<std::string> Checks("checks", desc(R"( Comma-separated list of globs with optional '-' @@ -466,10 +465,9 @@ createOptionsProvider(llvm::IntrusiveRefCntPtr<vfs::FileSystem> FS) { } static llvm::IntrusiveRefCntPtr<vfs::FileSystem> -getVfsFromFile(const std::string &OverlayFile, - llvm::IntrusiveRefCntPtr<vfs::FileSystem> BaseFS) { +getVfsFromFile(const std::string &OverlayFile, vfs::FileSystem &BaseFS) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer = - BaseFS->getBufferForFile(OverlayFile); + BaseFS.getBufferForFile(OverlayFile); if (!Buffer) { llvm::errs() << "Can't load virtual filesystem overlay file '" << OverlayFile << "': " << Buffer.getError().message() @@ -585,7 +583,7 @@ static llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> createBaseFS() { if (!VfsOverlay.empty()) { IntrusiveRefCntPtr<vfs::FileSystem> VfsFromFile = - getVfsFromFile(VfsOverlay, BaseFS); + getVfsFromFile(VfsOverlay, *BaseFS); if (!VfsFromFile) return nullptr; BaseFS->pushOverlay(std::move(VfsFromFile)); diff --git a/clang-tools-extra/clang-tidy/tool/check_alphabetical_order.py b/clang-tools-extra/clang-tidy/tool/check_alphabetical_order.py new file mode 100644 index 0000000..66819ab --- /dev/null +++ b/clang-tools-extra/clang-tidy/tool/check_alphabetical_order.py @@ -0,0 +1,421 @@ +#!/usr/bin/env python3 +# +# ===-----------------------------------------------------------------------===# +# +# 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 +# +# ===-----------------------------------------------------------------------===# + +""" + +Clang-Tidy Alphabetical Order Checker +===================================== + +Normalize Clang-Tidy documentation with deterministic sorting for linting/tests. + +Behavior: +- Sort entries in docs/clang-tidy/checks/list.rst csv-table. +- Sort key sections in docs/ReleaseNotes.rst. +- Detect duplicated entries in 'Changes in existing checks'. + +Flags: + -o/--output Write normalized content to this path instead of updating docs. +""" + +import argparse +from collections import defaultdict +import io +from operator import itemgetter +import os +import re +import sys +from typing import ( + DefaultDict, + Final, + Iterable, + List, + NamedTuple, + Optional, + Sequence, + Tuple, +) + +# Matches a :doc:`label <path>` or :doc:`label` reference anywhere in text and +# captures the label. Used to sort bullet items alphabetically in ReleaseNotes +# items by their label. +DOC_LABEL_RN_RE: Final = re.compile(r":doc:`(?P<label>[^`<]+)\s*(?:<[^>]+>)?`") + +# Matches a single csv-table row line in list.rst that begins with a :doc: +# reference, capturing the label. Used to extract the sort key per row. +DOC_LINE_RE: Final = re.compile(r"^\s*:doc:`(?P<label>[^`<]+?)\s*<[^>]+>`.*$") + + +EXTRA_DIR: Final = os.path.join(os.path.dirname(__file__), "../..") +DOCS_DIR: Final = os.path.join(EXTRA_DIR, "docs") +CLANG_TIDY_DOCS_DIR: Final = os.path.join(DOCS_DIR, "clang-tidy") +CHECKS_DOCS_DIR: Final = os.path.join(CLANG_TIDY_DOCS_DIR, "checks") +LIST_DOC: Final = os.path.join(CHECKS_DOCS_DIR, "list.rst") +RELEASE_NOTES_DOC: Final = os.path.join(DOCS_DIR, "ReleaseNotes.rst") + + +# Label extracted from :doc:`...`. +CheckLabel = str +Lines = List[str] +BulletBlock = List[str] + +# Pair of the extracted label and its block +BulletItem = Tuple[CheckLabel, BulletBlock] + +# Index of the first line of a bullet block within the full lines list. +BulletStart = int + +# All occurrences for a given label. +DuplicateOccurrences = List[Tuple[BulletStart, BulletBlock]] + + +class BulletBlocks(NamedTuple): + """Structured result of parsing a bullet-list section. + + - prefix: lines before the first bullet within the section range. + - blocks: list of (label, block-lines) pairs for each bullet block. + - suffix: lines after the last bullet within the section range. + """ + + prefix: Lines + blocks: List[BulletItem] + suffix: Lines + + +class ScannedBlocks(NamedTuple): + """Result of scanning bullet blocks within a section range. + + - blocks_with_pos: list of (start_index, block_lines) for each bullet block. + - next_index: index where scanning stopped; start of the suffix region. + """ + + blocks_with_pos: List[Tuple[BulletStart, BulletBlock]] + next_index: int + + +def _scan_bullet_blocks(lines: Sequence[str], start: int, end: int) -> ScannedBlocks: + """Scan consecutive bullet blocks and return (blocks_with_pos, next_index). + + Each entry in blocks_with_pos is a tuple of (start_index, block_lines). + next_index is the index where scanning stopped (start of suffix). + """ + i = start + n = end + blocks_with_pos: List[Tuple[BulletStart, BulletBlock]] = [] + while i < n: + if not _is_bullet_start(lines[i]): + break + bstart = i + i += 1 + while i < n and not _is_bullet_start(lines[i]): + if ( + i + 1 < n + and set(lines[i + 1].rstrip("\n")) == {"^"} + and lines[i].strip() + ): + break + i += 1 + block: BulletBlock = list(lines[bstart:i]) + blocks_with_pos.append((bstart, block)) + return ScannedBlocks(blocks_with_pos, i) + + +def read_text(path: str) -> str: + with io.open(path, "r", encoding="utf-8") as f: + return f.read() + + +def write_text(path: str, content: str) -> None: + with io.open(path, "w", encoding="utf-8", newline="") as f: + f.write(content) + + +def _normalize_list_rst_lines(lines: Sequence[str]) -> List[str]: + """Return normalized content of checks list.rst as a list of lines.""" + out: List[str] = [] + i = 0 + n = len(lines) + + def check_name(line: str) -> Tuple[int, CheckLabel]: + if m := DOC_LINE_RE.match(line): + return (0, m.group("label")) + return (1, "") + + while i < n: + line = lines[i] + if line.lstrip().startswith(".. csv-table::"): + out.append(line) + i += 1 + + while i < n and (lines[i].startswith(" ") or lines[i].strip() == ""): + if DOC_LINE_RE.match(lines[i]): + break + out.append(lines[i]) + i += 1 + + entries: List[str] = [] + while i < n and lines[i].startswith(" "): + entries.append(lines[i]) + i += 1 + + entries_sorted = sorted(entries, key=check_name) + out.extend(entries_sorted) + continue + + out.append(line) + i += 1 + + return out + + +def normalize_list_rst(data: str) -> str: + """Normalize list.rst content and return a string.""" + lines = data.splitlines(True) + return "".join(_normalize_list_rst_lines(lines)) + + +def find_heading(lines: Sequence[str], title: str) -> Optional[int]: + """Find heading start index for a section underlined with ^ characters. + + The function looks for a line equal to `title` followed by a line that + consists solely of ^, which matches the ReleaseNotes style for subsection + headings used here. + + Returns index of the title line, or None if not found. + """ + for i in range(len(lines) - 1): + if lines[i].rstrip("\n") == title: + if ( + (underline := lines[i + 1].rstrip("\n")) + and set(underline) == {"^"} + and len(underline) == len(title) + ): + return i + return None + + +def extract_label(text: str) -> str: + if m := DOC_LABEL_RN_RE.search(text): + return m.group("label") + return text + + +def _is_bullet_start(line: str) -> bool: + return line.startswith("- ") + + +def _parse_bullet_blocks(lines: Sequence[str], start: int, end: int) -> BulletBlocks: + i = start + n = end + first_bullet = i + while first_bullet < n and not _is_bullet_start(lines[first_bullet]): + first_bullet += 1 + prefix: Lines = list(lines[i:first_bullet]) + + blocks: List[BulletItem] = [] + res = _scan_bullet_blocks(lines, first_bullet, n) + for _, block in res.blocks_with_pos: + key: CheckLabel = extract_label(block[0]) + blocks.append((key, block)) + + suffix: Lines = list(lines[res.next_index : n]) + return BulletBlocks(prefix, blocks, suffix) + + +def sort_blocks(blocks: Iterable[BulletItem]) -> List[BulletBlock]: + """Return blocks sorted deterministically by their extracted label. + + Duplicates are preserved; merging is left to authors to handle manually. + """ + return list(map(itemgetter(1), sorted(blocks, key=itemgetter(0)))) + + +def find_duplicate_entries( + lines: Sequence[str], title: str +) -> List[Tuple[CheckLabel, DuplicateOccurrences]]: + """Return detailed duplicate info as (key, [(start_idx, block_lines), ...]). + + start_idx is the 0-based index of the first line of the bullet block in + the original lines list. Only keys with more than one occurrence are + returned, and occurrences are listed in the order they appear. + """ + bounds = _find_section_bounds(lines, title, None) + if bounds is None: + return [] + _, sec_start, sec_end = bounds + + i = sec_start + n = sec_end + + while i < n and not _is_bullet_start(lines[i]): + i += 1 + + blocks_with_pos: List[Tuple[CheckLabel, BulletStart, BulletBlock]] = [] + res = _scan_bullet_blocks(lines, i, n) + for bstart, block in res.blocks_with_pos: + key = extract_label(block[0]) + blocks_with_pos.append((key, bstart, block)) + + grouped: DefaultDict[CheckLabel, DuplicateOccurrences] = defaultdict(list) + for key, start, block in blocks_with_pos: + grouped[key].append((start, block)) + + result: List[Tuple[CheckLabel, DuplicateOccurrences]] = [] + for key, occs in grouped.items(): + if len(occs) > 1: + result.append((key, occs)) + + result.sort(key=itemgetter(0)) + return result + + +def _find_section_bounds( + lines: Sequence[str], title: str, next_title: Optional[str] +) -> Optional[Tuple[int, int, int]]: + """Return (h_start, sec_start, sec_end) for section `title`. + + - h_start: index of the section title line + - sec_start: index of the first content line after underline + - sec_end: index of the first line of the next section title (or end) + """ + if (h_start := find_heading(lines, title)) is None: + return None + + sec_start = h_start + 2 + + # Determine end of section either from next_title or by scanning. + if next_title is not None: + if (h_end := find_heading(lines, next_title)) is None: + # Scan forward to the next heading-like underline. + h_end = sec_start + while h_end + 1 < len(lines): + if lines[h_end].strip() and set(lines[h_end + 1].rstrip("\n")) == {"^"}: + break + h_end += 1 + sec_end = h_end + else: + # Scan to end or until a heading underline is found. + h_end = sec_start + while h_end + 1 < len(lines): + if lines[h_end].strip() and set(lines[h_end + 1].rstrip("\n")) == {"^"}: + break + h_end += 1 + sec_end = h_end + + return h_start, sec_start, sec_end + + +def _normalize_release_notes_section( + lines: Sequence[str], title: str, next_title: Optional[str] +) -> List[str]: + """Normalize a single release-notes section and return updated lines.""" + if (bounds := _find_section_bounds(lines, title, next_title)) is None: + return list(lines) + _, sec_start, sec_end = bounds + + prefix, blocks, suffix = _parse_bullet_blocks(lines, sec_start, sec_end) + sorted_blocks = sort_blocks(blocks) + + new_section: List[str] = [] + new_section.extend(prefix) + for i_b, b in enumerate(sorted_blocks): + if i_b > 0 and ( + not new_section or (new_section and new_section[-1].strip() != "") + ): + new_section.append("\n") + new_section.extend(b) + new_section.extend(suffix) + + return list(lines[:sec_start]) + new_section + list(lines[sec_end:]) + + +def normalize_release_notes(lines: Sequence[str]) -> str: + sections = ["New checks", "New check aliases", "Changes in existing checks"] + + out = list(lines) + + for idx in range(len(sections) - 1, -1, -1): + title = sections[idx] + next_title = sections[idx + 1] if idx + 1 < len(sections) else None + out = _normalize_release_notes_section(out, title, next_title) + + return "".join(out) + + +def _emit_duplicate_report(lines: Sequence[str], title: str) -> Optional[str]: + if not (dups_detail := find_duplicate_entries(lines, title)): + return None + out: List[str] = [] + out.append(f"Error: Duplicate entries in '{title}':\n") + for key, occs in dups_detail: + out.append(f"\n-- Duplicate: {key}\n") + for start_idx, block in occs: + out.append(f"- At line {start_idx + 1}:\n") + out.append("".join(block)) + if not (block and block[-1].endswith("\n")): + out.append("\n") + return "".join(out) + + +def process_release_notes(out_path: str, rn_doc: str) -> int: + text = read_text(rn_doc) + lines = text.splitlines(True) + normalized = normalize_release_notes(lines) + write_text(out_path, normalized) + + # Prefer reporting ordering issues first; let diff fail the test. + if text != normalized: + sys.stderr.write( + "\nEntries in 'clang-tools-extra/docs/ReleaseNotes.rst' are not alphabetically sorted.\n" + "Fix the ordering by applying diff printed below.\n\n" + ) + return 0 + + # Ordering is clean then enforce duplicates. + if report := _emit_duplicate_report(lines, "Changes in existing checks"): + sys.stderr.write(report) + return 3 + return 0 + + +def process_checks_list(out_path: str, list_doc: str) -> int: + text = read_text(list_doc) + normalized = normalize_list_rst(text) + + if text != normalized: + sys.stderr.write( + "\nChecks in 'clang-tools-extra/docs/clang-tidy/checks/list.rst' csv-table are not alphabetically sorted.\n" + "Fix the ordering by applying diff printed below.\n\n" + ) + + write_text(out_path, normalized) + return 0 + + +def main(argv: Sequence[str]) -> int: + ap = argparse.ArgumentParser() + ap.add_argument("-o", "--output", dest="out", default=None) + args = ap.parse_args(argv) + + list_doc, rn_doc = (os.path.normpath(LIST_DOC), os.path.normpath(RELEASE_NOTES_DOC)) + + if args.out: + out_path = args.out + out_lower = os.path.basename(out_path).lower() + if "release" in out_lower: + return process_release_notes(out_path, rn_doc) + else: + return process_checks_list(out_path, list_doc) + + process_checks_list(list_doc, list_doc) + return process_release_notes(rn_doc, rn_doc) + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/clang-tools-extra/clang-tidy/tool/check_alphabetical_order_test.py b/clang-tools-extra/clang-tidy/tool/check_alphabetical_order_test.py new file mode 100644 index 0000000..48a3c76 --- /dev/null +++ b/clang-tools-extra/clang-tidy/tool/check_alphabetical_order_test.py @@ -0,0 +1,401 @@ +# 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 + +# To run these tests: +# python3 check_alphabetical_order_test.py -v + +import check_alphabetical_order as _mod +from contextlib import redirect_stderr +import io +import os +import tempfile +import textwrap +from typing import cast +import unittest + + +class TestAlphabeticalOrderCheck(unittest.TestCase): + def test_normalize_list_rst_sorts_rows(self) -> None: + input_text = textwrap.dedent( + """\ + .. csv-table:: Clang-Tidy checks + :header: "Name", "Offers fixes" + + :doc:`bugprone-virtual-near-miss <bugprone/virtual-near-miss>`, "Yes" + :doc:`cert-flp30-c <cert/flp30-c>`, + :doc:`abseil-cleanup-ctad <abseil/cleanup-ctad>`, "Yes" + A non-doc row that should stay after docs + """ + ) + + expected_text = textwrap.dedent( + """\ + .. csv-table:: Clang-Tidy checks + :header: "Name", "Offers fixes" + + :doc:`abseil-cleanup-ctad <abseil/cleanup-ctad>`, "Yes" + :doc:`bugprone-virtual-near-miss <bugprone/virtual-near-miss>`, "Yes" + :doc:`cert-flp30-c <cert/flp30-c>`, + A non-doc row that should stay after docs + """ + ) + + out_str = _mod.normalize_list_rst(input_text) + self.assertEqual(out_str, expected_text) + + def test_find_heading(self) -> None: + text = textwrap.dedent( + """\ + - Deprecated the :program:`clang-tidy` ``zircon`` module. All checks have been + moved to the ``fuchsia`` module instead. The ``zircon`` module will be removed + in the 24th release. + + New checks + ^^^^^^^^^^ + - New :doc:`bugprone-derived-method-shadowing-base-method + <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check. + """ + ) + lines = text.splitlines(True) + idx = _mod.find_heading(lines, "New checks") + self.assertEqual(idx, 4) + + def test_duplicate_detection_and_report(self) -> None: + # Ensure duplicate detection works properly when sorting is incorrect. + text = textwrap.dedent( + """\ + Changes in existing checks + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - Improved :doc:`bugprone-exception-escape + <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas: + exceptions from captures are now diagnosed, exceptions in the bodies of + lambdas that aren't actually invoked are not. + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + """ + ) + lines = text.splitlines(True) + report = _mod._emit_duplicate_report(lines, "Changes in existing checks") + self.assertIsNotNone(report) + report_str = cast(str, report) + + expected_report = textwrap.dedent( + """\ + Error: Duplicate entries in 'Changes in existing checks': + + -- Duplicate: - Improved :doc:`bugprone-easily-swappable-parameters + + - At line 4: + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - At line 14: + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + """ + ) + self.assertEqual(report_str, expected_report) + + def test_process_release_notes_with_unsorted_content(self) -> None: + # When content is not normalized, the function writes normalized text and returns 0. + rn_text = textwrap.dedent( + """\ + New checks + ^^^^^^^^^^ + + - New :doc:`readability-redundant-parentheses + <clang-tidy/checks/readability/redundant-parentheses>` check. + + Detect redundant parentheses. + + - New :doc:`bugprone-derived-method-shadowing-base-method + <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check. + + Finds derived class methods that shadow a (non-virtual) base class method. + + """ + ) + with tempfile.TemporaryDirectory() as td: + rn_doc = os.path.join(td, "ReleaseNotes.rst") + out_path = os.path.join(td, "out.rst") + with open(rn_doc, "w", encoding="utf-8") as f: + f.write(rn_text) + + buf = io.StringIO() + with redirect_stderr(buf): + rc = _mod.process_release_notes(out_path, rn_doc) + + self.assertEqual(rc, 0) + with open(out_path, "r", encoding="utf-8") as f: + out = f.read() + + expected_out = textwrap.dedent( + """\ + New checks + ^^^^^^^^^^ + + - New :doc:`bugprone-derived-method-shadowing-base-method + <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check. + + Finds derived class methods that shadow a (non-virtual) base class method. + + - New :doc:`readability-redundant-parentheses + <clang-tidy/checks/readability/redundant-parentheses>` check. + + Detect redundant parentheses. + + + """ + ) + + self.assertEqual(out, expected_out) + self.assertIn("not alphabetically sorted", buf.getvalue()) + + def test_process_release_notes_prioritizes_sorting_over_duplicates(self) -> None: + # Sorting is incorrect and duplicates exist, should report ordering issues first. + rn_text = textwrap.dedent( + """\ + Changes in existing checks + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - Improved :doc:`bugprone-exception-escape + <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas: + exceptions from captures are now diagnosed, exceptions in the bodies of + lambdas that aren't actually invoked are not. + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + """ + ) + with tempfile.TemporaryDirectory() as td: + rn_doc = os.path.join(td, "ReleaseNotes.rst") + out_path = os.path.join(td, "out.rst") + with open(rn_doc, "w", encoding="utf-8") as f: + f.write(rn_text) + + buf = io.StringIO() + with redirect_stderr(buf): + rc = _mod.process_release_notes(out_path, rn_doc) + self.assertEqual(rc, 0) + self.assertIn( + "Entries in 'clang-tools-extra/docs/ReleaseNotes.rst' are not alphabetically sorted.", + buf.getvalue(), + ) + + with open(out_path, "r", encoding="utf-8") as f: + out = f.read() + expected_out = textwrap.dedent( + """\ + Changes in existing checks + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - Improved :doc:`bugprone-exception-escape + <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas: + exceptions from captures are now diagnosed, exceptions in the bodies of + lambdas that aren't actually invoked are not. + + + """ + ) + self.assertEqual(out, expected_out) + + def test_process_release_notes_with_duplicates_fails(self) -> None: + # Sorting is already correct but duplicates exist, should return 3 and report. + rn_text = textwrap.dedent( + """\ + Changes in existing checks + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - Improved :doc:`bugprone-exception-escape + <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas: + exceptions from captures are now diagnosed, exceptions in the bodies of + lambdas that aren't actually invoked are not. + + """ + ) + with tempfile.TemporaryDirectory() as td: + rn_doc = os.path.join(td, "ReleaseNotes.rst") + out_path = os.path.join(td, "out.rst") + with open(rn_doc, "w", encoding="utf-8") as f: + f.write(rn_text) + + buf = io.StringIO() + with redirect_stderr(buf): + rc = _mod.process_release_notes(out_path, rn_doc) + + self.assertEqual(rc, 3) + expected_report = textwrap.dedent( + """\ + Error: Duplicate entries in 'Changes in existing checks': + + -- Duplicate: - Improved :doc:`bugprone-easily-swappable-parameters + + - At line 4: + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - At line 9: + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + """ + ) + self.assertEqual(buf.getvalue(), expected_report) + + with open(out_path, "r", encoding="utf-8") as f: + out = f.read() + self.assertEqual(out, rn_text) + + def test_release_notes_handles_nested_sub_bullets(self) -> None: + rn_text = textwrap.dedent( + """\ + Changes in existing checks + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - Improved :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals + <clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals>` check: + + - Fix-it handles callees with nested-name-specifier correctly. + + - ``if`` statements with init-statement (``if (auto X = ...; ...)``) are + handled correctly. + + - ``for`` loops are supported. + + - Improved :doc:`bugprone-exception-escape + <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas: + exceptions from captures are now diagnosed, exceptions in the bodies of + lambdas that aren't actually invoked are not. + + """ + ) + + out = _mod.normalize_release_notes(rn_text.splitlines(True)) + + expected_out = textwrap.dedent( + """\ + Changes in existing checks + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + - Improved :doc:`bugprone-easily-swappable-parameters + <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by + correcting a spelling mistake on its option + ``NamePrefixSuffixSilenceDissimilarityTreshold``. + + - Improved :doc:`bugprone-exception-escape + <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas: + exceptions from captures are now diagnosed, exceptions in the bodies of + lambdas that aren't actually invoked are not. + + - Improved :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals + <clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals>` check: + + - Fix-it handles callees with nested-name-specifier correctly. + + - ``if`` statements with init-statement (``if (auto X = ...; ...)``) are + handled correctly. + + - ``for`` loops are supported. + + + """ + ) + self.assertEqual(out, expected_out) + + def test_process_checks_list_normalizes_output(self) -> None: + list_text = textwrap.dedent( + """\ + .. csv-table:: List + :header: "Name", "Redirect", "Offers fixes" + + :doc:`cert-dcl16-c <cert/dcl16-c>`, :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes" + :doc:`cert-con36-c <cert/con36-c>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`, + :doc:`cert-dcl37-c <cert/dcl37-c>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes" + :doc:`cert-arr39-c <cert/arr39-c>`, :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`, + """ + ) + with tempfile.TemporaryDirectory() as td: + in_doc = os.path.join(td, "list.rst") + out_doc = os.path.join(td, "out.rst") + with open(in_doc, "w", encoding="utf-8") as f: + f.write(list_text) + buf = io.StringIO() + with redirect_stderr(buf): + rc = _mod.process_checks_list(out_doc, in_doc) + self.assertEqual(rc, 0) + self.assertIn( + "Checks in 'clang-tools-extra/docs/clang-tidy/checks/list.rst' csv-table are not alphabetically sorted.", + buf.getvalue(), + ) + self.assertEqual(rc, 0) + with open(out_doc, "r", encoding="utf-8") as f: + out = f.read() + + expected_out = textwrap.dedent( + """\ + .. csv-table:: List + :header: "Name", "Redirect", "Offers fixes" + + :doc:`cert-arr39-c <cert/arr39-c>`, :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`, + :doc:`cert-con36-c <cert/con36-c>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`, + :doc:`cert-dcl16-c <cert/dcl16-c>`, :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes" + :doc:`cert-dcl37-c <cert/dcl37-c>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes" + """ + ) + self.assertEqual(out, expected_out) + + +if __name__ == "__main__": + unittest.main() diff --git a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp index a22d235..1b12859 100644 --- a/clang-tools-extra/clang-tidy/utils/Aliasing.cpp +++ b/clang-tools-extra/clang-tidy/utils/Aliasing.cpp @@ -65,15 +65,9 @@ static bool hasPtrOrReferenceInStmt(const Stmt *S, const ValueDecl *Var) { if (isPtrOrReferenceForVar(S, Var)) return true; - for (const Stmt *Child : S->children()) { - if (!Child) - continue; - - if (hasPtrOrReferenceInStmt(Child, Var)) - return true; - } - - return false; + return llvm::any_of(S->children(), [&](const Stmt *Child) { + return Child && hasPtrOrReferenceInStmt(Child, Var); + }); } static bool refersToEnclosingLambdaCaptureByRef(const Decl *Func, diff --git a/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.cpp b/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.cpp index aacb4e3..d0659ad 100644 --- a/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.cpp +++ b/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.cpp @@ -141,7 +141,7 @@ BraceInsertionHints getBraceInsertionsHints(const Stmt *const S, // StartLoc points at the location of the opening brace to be inserted. SourceLocation EndLoc; - std::string ClosingInsertion; + StringRef ClosingInsertion; if (EndLocHint.isValid()) { EndLoc = EndLocHint; ClosingInsertion = "} "; diff --git a/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.h b/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.h index 879c84d..2b2d71f 100644 --- a/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.h +++ b/clang-tools-extra/clang-tidy/utils/BracesAroundStatement.h @@ -39,7 +39,7 @@ struct BraceInsertionHints { /// Constructor for a hint offering fix-its for brace insertion. Both /// positions must be valid. BraceInsertionHints(SourceLocation OpeningBracePos, - SourceLocation ClosingBracePos, std::string ClosingBrace) + SourceLocation ClosingBracePos, StringRef ClosingBrace) : DiagnosticPos(OpeningBracePos), OpeningBracePos(OpeningBracePos), ClosingBracePos(ClosingBracePos), ClosingBrace(ClosingBrace) { assert(offersFixIts()); @@ -64,7 +64,7 @@ struct BraceInsertionHints { private: SourceLocation OpeningBracePos; SourceLocation ClosingBracePos; - std::string ClosingBrace; + StringRef ClosingBrace; }; /// Create fix-it hints for braces that wrap the given statement when applied. diff --git a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp index 75a6daf..a807c95 100644 --- a/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp @@ -21,10 +21,7 @@ using llvm::SmallPtrSet; template <typename S> static bool isSetDifferenceEmpty(const S &S1, const S &S2) { - for (auto E : S1) - if (S2.count(E) == 0) - return false; - return true; + return llvm::none_of(S1, [&S2](const auto &E) { return !S2.contains(E); }); } // Extracts all Nodes keyed by ID from Matches and inserts them into Nodes. diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp index 5fd1b73..f766a1bc 100644 --- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp @@ -192,8 +192,7 @@ static bool isFunctionPointerConvertible(QualType From, QualType To) { // // The function should only be called in C++ mode. static bool isQualificationConvertiblePointer(QualType From, QualType To, - LangOptions LangOpts) { - + const LangOptions &LangOpts) { // [N4659 7.5 (1)] // A cv-decomposition of a type T is a sequence of cv_i and P_i such that T is // cv_0 P_0 cv_1 P_1 ... cv_n−1 P_n−1 cv_n U” for n > 0, @@ -562,17 +561,6 @@ ExceptionAnalyzer::throwsException(const Stmt *St, } } Results.merge(Uncaught); - } else if (const auto *Call = dyn_cast<CallExpr>(St)) { - if (const FunctionDecl *Func = Call->getDirectCallee()) { - const ExceptionInfo Excs = - throwsException(Func, Caught, CallStack, Call->getBeginLoc()); - Results.merge(Excs); - } - } else if (const auto *Construct = dyn_cast<CXXConstructExpr>(St)) { - const ExceptionInfo Excs = - throwsException(Construct->getConstructor(), Caught, CallStack, - Construct->getBeginLoc()); - Results.merge(Excs); } else if (const auto *DefaultInit = dyn_cast<CXXDefaultInitExpr>(St)) { const ExceptionInfo Excs = throwsException(DefaultInit->getExpr(), Caught, CallStack); @@ -602,10 +590,26 @@ ExceptionAnalyzer::throwsException(const Stmt *St, Results.merge(Excs); } } else { + // Check whether any of this node's subexpressions throws. for (const Stmt *Child : St->children()) { const ExceptionInfo Excs = throwsException(Child, Caught, CallStack); Results.merge(Excs); } + + // If this node is a call to a function or constructor, also check + // whether the call itself throws. + if (const auto *Call = dyn_cast<CallExpr>(St)) { + if (const FunctionDecl *Func = Call->getDirectCallee()) { + const ExceptionInfo Excs = + throwsException(Func, Caught, CallStack, Call->getBeginLoc()); + Results.merge(Excs); + } + } else if (const auto *Construct = dyn_cast<CXXConstructExpr>(St)) { + const ExceptionInfo Excs = + throwsException(Construct->getConstructor(), Caught, CallStack, + Construct->getBeginLoc()); + Results.merge(Excs); + } } return Results; } diff --git a/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp b/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp index 0375d0f..45fcacf 100644 --- a/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp +++ b/clang-tools-extra/clang-tidy/utils/ExprSequence.cpp @@ -148,12 +148,9 @@ bool ExprSequence::inSequence(const Stmt *Before, const Stmt *After) const { // If 'After' is a parent of 'Before' or is sequenced after one of these // parents, we know that it is sequenced after 'Before'. - for (const Stmt *Parent : BeforeParents) { - if (Parent == After || inSequence(Parent, After)) - return true; - } - - return false; + return llvm::any_of(BeforeParents, [&](const Stmt *Parent) { + return Parent == After || inSequence(Parent, After); + }); } bool ExprSequence::potentiallyAfter(const Stmt *After, diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp index 127de30..d210b00 100644 --- a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp +++ b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp @@ -624,7 +624,6 @@ bool FormatStringConverter::HandlePrintfSpecifier(const PrintfSpecifier &FS, const char *StartSpecifier, unsigned SpecifierLen, const TargetInfo &Target) { - const size_t StartSpecifierPos = StartSpecifier - PrintfFormatString.data(); assert(StartSpecifierPos + SpecifierLen <= PrintfFormatString.size()); @@ -701,6 +700,7 @@ void FormatStringConverter::finalizeFormatText() { /// Append literal parts of the format text, reinstating escapes as required. void FormatStringConverter::appendFormatText(const StringRef Text) { for (const char Ch : Text) { + const auto UCh = static_cast<unsigned char>(Ch); if (Ch == '\a') StandardFormatString += "\\a"; else if (Ch == '\b') @@ -725,10 +725,10 @@ void FormatStringConverter::appendFormatText(const StringRef Text) { } else if (Ch == '}') { StandardFormatString += "}}"; FormatStringNeededRewriting = true; - } else if (Ch < 32) { + } else if (UCh < 32) { StandardFormatString += "\\x"; - StandardFormatString += llvm::hexdigit(Ch >> 4, true); - StandardFormatString += llvm::hexdigit(Ch & 0xf, true); + StandardFormatString += llvm::hexdigit(UCh >> 4, true); + StandardFormatString += llvm::hexdigit(UCh & 0xf, true); } else StandardFormatString += Ch; } diff --git a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp index 0f20fde..06d6caa 100644 --- a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "LexerUtils.h" -#include "clang/AST/AST.h" #include "clang/Basic/SourceManager.h" #include <optional> #include <utility> @@ -170,7 +169,6 @@ static bool breakAndReturnEndPlus1Token(const Stmt &S) { static SourceLocation getSemicolonAfterStmtEndLoc(const SourceLocation &EndLoc, const SourceManager &SM, const LangOptions &LangOpts) { - if (EndLoc.isMacroID()) { // Assuming EndLoc points to a function call foo within macro F. // This method is supposed to return location of the semicolon within @@ -206,7 +204,6 @@ static SourceLocation getSemicolonAfterStmtEndLoc(const SourceLocation &EndLoc, SourceLocation getUnifiedEndLoc(const Stmt &S, const SourceManager &SM, const LangOptions &LangOpts) { - const Stmt *LastChild = &S; while (!LastChild->children().empty() && !breakAndReturnEnd(*LastChild) && !breakAndReturnEndPlus1Token(*LastChild)) { diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.cpp b/clang-tools-extra/clang-tidy/utils/Matchers.cpp index 4382745..b1591fb 100644 --- a/clang-tools-extra/clang-tidy/utils/Matchers.cpp +++ b/clang-tools-extra/clang-tidy/utils/Matchers.cpp @@ -27,7 +27,6 @@ MatchesAnyListedTypeNameMatcher::~MatchesAnyListedTypeNameMatcher() = default; bool MatchesAnyListedTypeNameMatcher::matches( const QualType &Node, ast_matchers::internal::ASTMatchFinder *Finder, ast_matchers::internal::BoundNodesTreeBuilder *Builder) const { - if (NameMatchers.empty()) return false; diff --git a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp index d7dad62..6fa62302 100644 --- a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.cpp @@ -9,7 +9,6 @@ #include "TransformerClangTidyCheck.h" #include "clang/Basic/DiagnosticIDs.h" #include "clang/Lex/Preprocessor.h" -#include "llvm/ADT/STLExtras.h" #include <optional> namespace clang::tidy::utils { @@ -66,7 +65,7 @@ TransformerClangTidyCheck::TransformerClangTidyCheck(StringRef Name, // we would be accessing `getLangOpts` and `Options` before the underlying // `ClangTidyCheck` instance was properly initialized. TransformerClangTidyCheck::TransformerClangTidyCheck( - std::function<std::optional<RewriteRuleWith<std::string>>( + llvm::function_ref<std::optional<RewriteRuleWith<std::string>>( const LangOptions &, const OptionsView &)> MakeRule, StringRef Name, ClangTidyContext *Context) diff --git a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h index e77f84b..da8606f 100644 --- a/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h +++ b/clang-tools-extra/clang-tidy/utils/TransformerClangTidyCheck.h @@ -48,8 +48,9 @@ public: /// /// See \c setRule for constraints on the rule. TransformerClangTidyCheck( - std::function<std::optional<transformer::RewriteRuleWith<std::string>>( - const LangOptions &, const OptionsView &)> + llvm::function_ref< + std::optional<transformer::RewriteRuleWith<std::string>>( + const LangOptions &, const OptionsView &)> MakeRule, StringRef Name, ClangTidyContext *Context); diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp index 98a5d40..dde6e9a 100644 --- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp +++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp @@ -24,11 +24,9 @@ static bool hasDeletedCopyConstructor(QualType Type) { auto *Record = Type->getAsCXXRecordDecl(); if (!Record || !Record->hasDefinition()) return false; - for (const auto *Constructor : Record->ctors()) { - if (Constructor->isCopyConstructor() && Constructor->isDeleted()) - return true; - } - return false; + return llvm::any_of(Record->ctors(), [](const auto *Constructor) { + return Constructor->isCopyConstructor() && Constructor->isDeleted(); + }); } std::optional<bool> isExpensiveToCopy(QualType Type, @@ -70,14 +68,10 @@ bool recordIsTriviallyDefaultConstructible(const RecordDecl &RecordDecl, return false; } // If all its direct bases are trivially constructible. - for (const CXXBaseSpecifier &Base : ClassDecl->bases()) { - if (!isTriviallyDefaultConstructible(Base.getType(), Context)) - return false; - if (Base.isVirtual()) - return false; - } - - return true; + return llvm::all_of(ClassDecl->bases(), [&](const CXXBaseSpecifier &Base) { + return isTriviallyDefaultConstructible(Base.getType(), Context) && + !Base.isVirtual(); + }); } // Based on QualType::isTrivial. diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp index 8b7019b..ab584cb 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp @@ -55,7 +55,7 @@ AST_MATCHER(Expr, hasSideEffects) { } // namespace static auto -makeExprMatcher(ast_matchers::internal::Matcher<Expr> ArgumentMatcher, +makeExprMatcher(const ast_matchers::internal::Matcher<Expr> &ArgumentMatcher, ArrayRef<StringRef> MethodNames, ArrayRef<StringRef> FreeNames) { return expr( @@ -199,7 +199,7 @@ void UseRangesCheck::check(const MatchFinder::MatchResult &Result) { if (!NodeStr.consume_front(FuncDecl)) continue; Function = Value.get<FunctionDecl>(); - size_t Index; + size_t Index = 0; if (NodeStr.getAsInteger(10, Index)) { llvm_unreachable("Unable to extract replacer index"); } |
