https://github.com/PiotrZSL updated https://github.com/llvm/llvm-project/pull/86448
>From c99ba980b0b242fced57fb323c5069d856c68810 Mon Sep 17 00:00:00 2001 From: Piotr Zegar <m...@piotrzegar.pl> Date: Sun, 31 Mar 2024 12:16:53 +0000 Subject: [PATCH 1/6] fix --- clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h | 1 + clang-tools-extra/clang-tidy/abseil/CMakeLists.txt | 6 ++++++ .../clang-tidy/abseil/StringFindStrContainsCheck.cpp | 7 +++++-- .../abseil/UpgradeDurationConversionsCheck.cpp | 2 +- clang-tools-extra/clang-tidy/altera/CMakeLists.txt | 6 ++++++ clang-tools-extra/clang-tidy/android/CMakeLists.txt | 6 ++++++ clang-tools-extra/clang-tidy/boost/CMakeLists.txt | 6 ++++++ clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt | 6 ++++++ .../clang-tidy/bugprone/IncDecInConditionsCheck.cpp | 3 +++ .../clang-tidy/bugprone/InfiniteLoopCheck.cpp | 8 ++++---- .../bugprone/MultipleNewInOneExpressionCheck.cpp | 2 +- .../clang-tidy/bugprone/StringConstructorCheck.cpp | 4 ++-- .../bugprone/UnhandledExceptionAtNewCheck.cpp | 3 +++ clang-tools-extra/clang-tidy/cert/CMakeLists.txt | 6 ++++++ .../clang-tidy/concurrency/CMakeLists.txt | 6 ++++++ .../clang-tidy/cppcoreguidelines/CMakeLists.txt | 6 ++++++ .../VirtualClassDestructorCheck.cpp | 2 ++ clang-tools-extra/clang-tidy/darwin/CMakeLists.txt | 6 ++++++ clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt | 6 ++++++ clang-tools-extra/clang-tidy/google/CMakeLists.txt | 6 ++++++ clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt | 6 ++++++ .../clang-tidy/linuxkernel/CMakeLists.txt | 5 +++++ clang-tools-extra/clang-tidy/llvm/CMakeLists.txt | 6 ++++++ clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt | 6 ++++++ .../clang-tidy/llvmlibc/NamespaceConstants.h | 1 + clang-tools-extra/clang-tidy/misc/CMakeLists.txt | 5 +++++ .../clang-tidy/modernize/AvoidCArraysCheck.cpp | 4 ++-- .../clang-tidy/modernize/CMakeLists.txt | 6 ++++++ .../clang-tidy/modernize/LoopConvertCheck.cpp | 4 ++-- .../clang-tidy/modernize/UseEqualsDefaultCheck.cpp | 2 +- .../clang-tidy/modernize/UseEqualsDeleteCheck.cpp | 10 +++++----- .../modernize/UseTransparentFunctorsCheck.cpp | 6 +++--- clang-tools-extra/clang-tidy/mpi/CMakeLists.txt | 6 ++++++ clang-tools-extra/clang-tidy/objc/CMakeLists.txt | 6 ++++++ clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp | 6 +++--- clang-tools-extra/clang-tidy/openmp/CMakeLists.txt | 6 ++++++ .../clang-tidy/performance/CMakeLists.txt | 6 ++++++ .../performance/UnnecessaryCopyInitialization.cpp | 2 +- .../clang-tidy/portability/CMakeLists.txt | 6 ++++++ .../clang-tidy/readability/CMakeLists.txt | 7 +++++++ .../readability/ConvertMemberFunctionsToStatic.cpp | 3 +++ .../readability/FunctionCognitiveComplexityCheck.cpp | 12 ++++++------ .../readability/MakeMemberFunctionConstCheck.cpp | 6 +++++- .../readability/RedundantDeclarationCheck.cpp | 3 +++ .../readability/RedundantSmartptrGetCheck.cpp | 4 ++-- .../ReferenceToConstructedTemporaryCheck.cpp | 2 +- 46 files changed, 197 insertions(+), 37 deletions(-) diff --git a/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h b/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h index 1eef86ddc00b9..7a636ef8ebb95 100644 --- a/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h +++ b/clang-tools-extra/clang-tidy/abseil/AbseilMatcher.h @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#pragma once #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include <algorithm> diff --git a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt index 489d732abaa8d..8eca56ead7f8e 100644 --- a/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/abseil/CMakeLists.txt @@ -44,3 +44,9 @@ clang_target_link_libraries(clangTidyAbseilModule clangTooling clangTransformer ) + + set_target_properties(obj.clangTidyAbseilModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp index 28b2f81fdc8c8..0c036e31426aa 100644 --- a/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/StringFindStrContainsCheck.cpp @@ -30,9 +30,12 @@ using ::clang::transformer::makeRule; using ::clang::transformer::node; using ::clang::transformer::RewriteRuleWith; +namespace { + AST_MATCHER(Type, isCharType) { return Node.isCharType(); } +} -static const char DefaultStringLikeClasses[] = "::std::basic_string;" +static const char DefaultStringLikeClasses2[] = "::std::basic_string;" "::std::basic_string_view;" "::absl::string_view"; static const char DefaultAbseilStringsMatchHeader[] = "absl/strings/match.h"; @@ -84,7 +87,7 @@ StringFindStrContainsCheck::StringFindStrContainsCheck( StringRef Name, ClangTidyContext *Context) : TransformerClangTidyCheck(Name, Context), StringLikeClassesOption(utils::options::parseStringList( - Options.get("StringLikeClasses", DefaultStringLikeClasses))), + Options.get("StringLikeClasses", DefaultStringLikeClasses2))), AbseilStringsMatchHeaderOption(Options.get( "AbseilStringsMatchHeader", DefaultAbseilStringsMatchHeader)) { setRule( diff --git a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp index 8e27e8e3e0c2b..8168def2b98ad 100644 --- a/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp @@ -139,7 +139,7 @@ void UpgradeDurationConversionsCheck::check( // We gather source locations from template matches not in template // instantiations for future matches. - internal::Matcher<Stmt> IsInsideTemplate = + ast_matchers::internal::Matcher<Stmt> IsInsideTemplate = hasAncestor(decl(anyOf(classTemplateDecl(), functionTemplateDecl()))); if (!match(IsInsideTemplate, *ArgExpr, *Result.Context).empty()) MatchedTemplateLocations.insert(Loc); diff --git a/clang-tools-extra/clang-tidy/altera/CMakeLists.txt b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt index f885993c3c9e7..5e373d831f25c 100644 --- a/clang-tools-extra/clang-tidy/altera/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/altera/CMakeLists.txt @@ -27,3 +27,9 @@ clang_target_link_libraries(clangTidyAlteraModule clangBasic clangLex ) + + set_target_properties(obj.clangTidyAlteraModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/android/CMakeLists.txt b/clang-tools-extra/clang-tidy/android/CMakeLists.txt index c33d0daf4e25c..27533cf3044e7 100644 --- a/clang-tools-extra/clang-tidy/android/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/android/CMakeLists.txt @@ -38,3 +38,9 @@ clang_target_link_libraries(clangTidyAndroidModule clangBasic clangLex ) + + set_target_properties(obj.clangTidyAndroidModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/boost/CMakeLists.txt b/clang-tools-extra/clang-tidy/boost/CMakeLists.txt index 167b6fab774b7..8495a4252532c 100644 --- a/clang-tools-extra/clang-tidy/boost/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/boost/CMakeLists.txt @@ -23,3 +23,9 @@ clang_target_link_libraries(clangTidyBoostModule clangBasic clangLex ) + + set_target_properties(obj.clangTidyBoostModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 2d303191f8865..c0f5ea69e9279 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -111,3 +111,9 @@ clang_target_link_libraries(clangTidyBugproneModule clangTooling clangTransformer ) + + set_target_properties(obj.clangTidyBugproneModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp index 9b3b01eb02683..051765c6f68c1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/IncDecInConditionsCheck.cpp @@ -15,6 +15,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { + namespace { AST_MATCHER(BinaryOperator, isLogicalOperator) { return Node.isLogicalOp(); } AST_MATCHER(UnaryOperator, isUnaryPrePostOperator) { @@ -26,6 +27,8 @@ AST_MATCHER(CXXOperatorCallExpr, isPrePostOperator) { Node.getOperator() == OO_MinusMinus; } +} + void IncDecInConditionsCheck::registerMatchers(MatchFinder *Finder) { auto OperatorMatcher = expr( anyOf(binaryOperator(anyOf(isComparisonOperator(), isLogicalOperator())), diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp index e329588290cd4..b91c585489c78 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp @@ -33,11 +33,11 @@ AST_MATCHER(FunctionType, typeHasNoReturnAttr) { } // namespace ast_matchers namespace tidy::bugprone { -static internal::Matcher<Stmt> -loopEndingStmt(internal::Matcher<Stmt> Internal) { - internal::Matcher<QualType> isNoReturnFunType = +static ast_matchers::internal::Matcher<Stmt> +loopEndingStmt(ast_matchers::internal::Matcher<Stmt> Internal) { + ast_matchers::internal::Matcher<QualType> isNoReturnFunType = ignoringParens(functionType(typeHasNoReturnAttr())); - internal::Matcher<Decl> isNoReturnDecl = + ast_matchers::internal::Matcher<Decl> isNoReturnDecl = anyOf(declHasNoReturnAttr(), functionDecl(hasType(isNoReturnFunType)), varDecl(hasType(blockPointerType(pointee(isNoReturnFunType))))); diff --git a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp index 41191a3cfed23..8e42153e8df42 100644 --- a/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/MultipleNewInOneExpressionCheck.cpp @@ -49,7 +49,6 @@ bool isExprValueStored(const Expr *E, ASTContext &C) { return isa<CallExpr, CXXConstructExpr>(ParentE); } -} // namespace AST_MATCHER_P(CXXTryStmt, hasHandlerFor, ast_matchers::internal::Matcher<QualType>, InnerMatcher) { @@ -74,6 +73,7 @@ AST_MATCHER(CXXNewExpr, mayThrow) { return !OperatorNew->getType()->castAs<FunctionProtoType>()->isNothrow(); } +} // namespace void MultipleNewInOneExpressionCheck::registerMatchers(MatchFinder *Finder) { auto BadAllocType = recordType(hasDeclaration(cxxRecordDecl(hasName("::std::bad_alloc")))); diff --git a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp index 8ae4351ac2830..3376fb6d35ef4 100644 --- a/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -17,7 +17,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { namespace { -AST_MATCHER_P(IntegerLiteral, isBiggerThan, unsigned, N) { +AST_MATCHER_P(IntegerLiteral, isBiggerThan2, unsigned, N) { return Node.getValue().getZExtValue() > N; } @@ -61,7 +61,7 @@ void StringConstructorCheck::registerMatchers(MatchFinder *Finder) { unaryOperator(hasOperatorName("-"), hasUnaryOperand(integerLiteral(unless(equals(0))))))); const auto LargeLengthExpr = expr(ignoringParenImpCasts( - integerLiteral(isBiggerThan(LargeLengthThreshold)))); + integerLiteral(isBiggerThan2(LargeLengthThreshold)))); const auto CharPtrType = type(anyOf(pointerType(), arrayType())); // Match a string-literal; even through a declaration with initializer. diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp index b160e7259905b..d0109b5b4301e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledExceptionAtNewCheck.cpp @@ -14,6 +14,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::bugprone { + namespace { AST_MATCHER_P(CXXTryStmt, hasHandlerFor, ast_matchers::internal::Matcher<QualType>, InnerMatcher) { for (unsigned NH = Node.getNumHandlers(), I = 0; I < NH; ++I) { @@ -37,6 +38,8 @@ AST_MATCHER(CXXNewExpr, mayThrow) { return !OperatorNew->getType()->castAs<FunctionProtoType>()->isNothrow(); } +} + UnhandledExceptionAtNewCheck::UnhandledExceptionAtNewCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context) {} diff --git a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt index 882735c9d1e0d..d42f2e1672816 100644 --- a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt @@ -41,3 +41,9 @@ clang_target_link_libraries(clangTidyCERTModule clangBasic clangLex ) + + set_target_properties(obj.clangTidyCERTModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/concurrency/CMakeLists.txt b/clang-tools-extra/clang-tidy/concurrency/CMakeLists.txt index 3dab6aaf8aea2..04f3ca515c29e 100644 --- a/clang-tools-extra/clang-tidy/concurrency/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/concurrency/CMakeLists.txt @@ -26,3 +26,9 @@ clang_target_link_libraries(clangTidyConcurrencyModule clangSerialization clangTooling ) + + set_target_properties(obj.clangTidyConcurrencyModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt index eb35bbc6a538f..06bd6629501ff 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -59,3 +59,9 @@ clang_target_link_libraries(clangTidyCppCoreGuidelinesModule clangSerialization clangTooling ) + + set_target_properties(obj.clangTidyCppCoreGuidelinesModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp index aa70b3896f16d..b6e3bdecb3312 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/VirtualClassDestructorCheck.cpp @@ -18,6 +18,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::cppcoreguidelines { + namespace { AST_MATCHER(CXXRecordDecl, hasPublicVirtualOrProtectedNonVirtualDestructor) { // We need to call Node.getDestructor() instead of matching a // CXXDestructorDecl. Otherwise, tests will fail for class templates, since @@ -33,6 +34,7 @@ AST_MATCHER(CXXRecordDecl, hasPublicVirtualOrProtectedNonVirtualDestructor) { !Destructor->isVirtual())); } +} void VirtualClassDestructorCheck::registerMatchers(MatchFinder *Finder) { ast_matchers::internal::Matcher<CXXRecordDecl> InheritsVirtualMethod = hasAnyBase(hasType(cxxRecordDecl(has(cxxMethodDecl(isVirtual()))))); diff --git a/clang-tools-extra/clang-tidy/darwin/CMakeLists.txt b/clang-tools-extra/clang-tidy/darwin/CMakeLists.txt index 6f6b3607b3ec6..bd84b1e566d12 100644 --- a/clang-tools-extra/clang-tidy/darwin/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/darwin/CMakeLists.txt @@ -25,3 +25,9 @@ clang_target_link_libraries(clangTidyDarwinModule clangBasic clangLex ) + + set_target_properties(obj.clangTidyDarwinModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt index d0e68bfec47fe..330659ad3d3f8 100644 --- a/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt @@ -30,3 +30,9 @@ clang_target_link_libraries(clangTidyFuchsiaModule clangBasic clangLex ) + + set_target_properties(obj.clangTidyFuchsiaModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/google/CMakeLists.txt b/clang-tools-extra/clang-tidy/google/CMakeLists.txt index fcba2b1b214ad..90fa61987f5f1 100644 --- a/clang-tools-extra/clang-tidy/google/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/google/CMakeLists.txt @@ -39,3 +39,9 @@ clang_target_link_libraries(clangTidyGoogleModule clangBasic clangLex ) + + set_target_properties(obj.clangTidyGoogleModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt b/clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt index 132fbaccccf8a..21a8b6c2ea71c 100644 --- a/clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/hicpp/CMakeLists.txt @@ -35,3 +35,9 @@ clang_target_link_libraries(clangTidyHICPPModule clangLex clangSerialization ) + + set_target_properties(obj.clangTidyHICPPModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt b/clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt index 403589d947590..0bea35e7191e1 100644 --- a/clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/linuxkernel/CMakeLists.txt @@ -23,3 +23,8 @@ clang_target_link_libraries(clangTidyLinuxKernelModule clangBasic clangLex ) + set_target_properties(obj.clangTidyLinuxKernelModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt b/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt index b56498bdc8c4b..c5c8e09bbc88b 100644 --- a/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/llvm/CMakeLists.txt @@ -29,3 +29,9 @@ clang_target_link_libraries(clangTidyLLVMModule clangLex clangTooling ) + + set_target_properties(obj.clangTidyLLVMModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt b/clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt index b071cfd67dcf4..ba29072acc566 100644 --- a/clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/llvmlibc/CMakeLists.txt @@ -28,3 +28,9 @@ clang_target_link_libraries(clangTidyLLVMLibcModule clangLex clangTooling ) + + set_target_properties(obj.clangTidyLLVMLibcModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/llvmlibc/NamespaceConstants.h b/clang-tools-extra/clang-tidy/llvmlibc/NamespaceConstants.h index 7d4120085b866..78adfa8f2f306 100644 --- a/clang-tools-extra/clang-tidy/llvmlibc/NamespaceConstants.h +++ b/clang-tools-extra/clang-tidy/llvmlibc/NamespaceConstants.h @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#pragma once #include "llvm/ADT/StringRef.h" 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 d9ec268650c05..3e0a62905b920 100644 --- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt @@ -69,3 +69,8 @@ target_link_libraries(clangTidyMiscModule PRIVATE clangIncludeCleaner ) + set_target_properties(obj.clangTidyMiscModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp index 89790ea70cf22..a6f5f66578006 100644 --- a/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/AvoidCArraysCheck.cpp @@ -20,7 +20,7 @@ AST_MATCHER(clang::TypeLoc, hasValidBeginLoc) { return Node.getBeginLoc().isValid(); } -AST_MATCHER_P(clang::TypeLoc, hasType, +AST_MATCHER_P(clang::TypeLoc, hasTypeLoc, clang::ast_matchers::internal::Matcher<clang::Type>, InnerMatcher) { const clang::Type *TypeNode = Node.getTypePtr(); @@ -59,7 +59,7 @@ void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) { unless(parmVarDecl()))))); Finder->addMatcher( - typeLoc(hasValidBeginLoc(), hasType(arrayType()), + typeLoc(hasValidBeginLoc(), hasTypeLoc(arrayType()), unless(anyOf(hasParent(parmVarDecl(isArgvOfMain())), hasParent(varDecl(isExternC())), hasParent(fieldDecl( diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 8005d6e91c060..c78c03c77ad54 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -66,3 +66,9 @@ clang_target_link_libraries(clangTidyModernizeModule clangLex clangTooling ) + +set_target_properties(obj.clangTidyModernizeModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp index 3229e302eb432..9b05c3a7425c5 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertCheck.cpp @@ -94,7 +94,7 @@ static StatementMatcher incrementVarMatcher() { } static StatementMatcher -arrayConditionMatcher(internal::Matcher<Expr> LimitExpr) { +arrayConditionMatcher(ast_matchers::internal::Matcher<Expr> LimitExpr) { return binaryOperator( anyOf(allOf(hasOperatorName("<"), hasLHS(integerComparisonMatcher()), hasRHS(LimitExpr)), @@ -209,7 +209,7 @@ StatementMatcher makeIteratorLoopMatcher(bool IsReverse) { // 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 = + ast_matchers::internal::Matcher<VarDecl> TestDerefReturnsByValue = hasType(hasUnqualifiedDesugaredType( recordType(hasDeclaration(cxxRecordDecl(hasMethod(cxxMethodDecl( hasOverloadedOperatorName("*"), diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp index 93151024064b4..9a47bcaa0ed88 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp @@ -48,7 +48,7 @@ static std::set<const Type *> getAllDirectBases(const CXXRecordDecl *Record) { /// Returns a matcher that matches member expressions where the base is /// the variable declared as \p Var and the accessed member is the one declared /// as \p Field. -internal::Matcher<Expr> accessToFieldInVar(const FieldDecl *Field, +ast_matchers::internal::Matcher<Expr> accessToFieldInVar(const FieldDecl *Field, const ValueDecl *Var) { return ignoringImpCasts( memberExpr(hasObjectExpression(declRefExpr(to(varDecl(equalsNode(Var))))), diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp index 9561cc71183d9..8c62f4e08fb75 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp @@ -31,7 +31,7 @@ AST_MATCHER(FunctionDecl, hasAnyDefinition) { AST_MATCHER(Decl, isUsed) { return Node.isUsed(); } -AST_MATCHER(CXXMethodDecl, isSpecialFunction) { +AST_MATCHER(CXXMethodDecl, isSpecialFunction2) { if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(&Node)) return Constructor->isDefaultConstructor() || Constructor->isCopyOrMoveConstructor(); @@ -41,7 +41,7 @@ AST_MATCHER(CXXMethodDecl, isSpecialFunction) { } } // namespace -static const char SpecialFunction[] = "SpecialFunction"; +static const char SpecialFunction2[] = "SpecialFunction"; static const char DeletedNotPublic[] = "DeletedNotPublic"; UseEqualsDeleteCheck::UseEqualsDeleteCheck(StringRef Name, @@ -54,7 +54,7 @@ void UseEqualsDeleteCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) { - auto PrivateSpecialFn = cxxMethodDecl(isPrivate(), isSpecialFunction()); + auto PrivateSpecialFn = cxxMethodDecl(isPrivate(), isSpecialFunction2()); Finder->addMatcher( cxxMethodDecl( @@ -63,7 +63,7 @@ void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) { // defined. unless(ofClass(hasMethod(cxxMethodDecl(unless(PrivateSpecialFn), unless(hasAnyDefinition())))))) - .bind(SpecialFunction), + .bind(SpecialFunction2), this); Finder->addMatcher( @@ -73,7 +73,7 @@ void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) { void UseEqualsDeleteCheck::check(const MatchFinder::MatchResult &Result) { if (const auto *Func = - Result.Nodes.getNodeAs<CXXMethodDecl>(SpecialFunction)) { + Result.Nodes.getNodeAs<CXXMethodDecl>(SpecialFunction2)) { SourceLocation EndLoc = Lexer::getLocForEndOfToken( Func->getEndLoc(), 0, *Result.SourceManager, getLangOpts()); diff --git a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp index 2223a1999f736..957492dfe4311 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp @@ -62,7 +62,7 @@ void UseTransparentFunctorsCheck::registerMatchers(MatchFinder *Finder) { this); } -static const StringRef Message = "prefer transparent functors '%0<>'"; +static const StringRef MessageDiag = "prefer transparent functors '%0<>'"; template <typename T> static T getInnerTypeLocAs(TypeLoc Loc) { T Result; @@ -79,7 +79,7 @@ void UseTransparentFunctorsCheck::check( Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("FunctorClass"); if (const auto *FuncInst = Result.Nodes.getNodeAs<CXXConstructExpr>("FuncInst")) { - diag(FuncInst->getBeginLoc(), Message) << FuncClass->getName(); + diag(FuncInst->getBeginLoc(), MessageDiag) << FuncClass->getName(); return; } @@ -117,7 +117,7 @@ void UseTransparentFunctorsCheck::check( SourceLocation ReportLoc = FunctorLoc.getLocation(); if (ReportLoc.isInvalid()) return; - diag(ReportLoc, Message) << FuncClass->getName() + diag(ReportLoc, MessageDiag) << FuncClass->getName() << FixItHint::CreateRemoval( FunctorTypeLoc.getArgLoc(0).getSourceRange()); } diff --git a/clang-tools-extra/clang-tidy/mpi/CMakeLists.txt b/clang-tools-extra/clang-tidy/mpi/CMakeLists.txt index 717683042f524..ef201d8519c38 100644 --- a/clang-tools-extra/clang-tidy/mpi/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/mpi/CMakeLists.txt @@ -27,3 +27,9 @@ clang_target_link_libraries(clangTidyMPIModule clangTooling clangStaticAnalyzerCheckers ) + + set_target_properties(obj.clangTidyMPIModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/objc/CMakeLists.txt b/clang-tools-extra/clang-tidy/objc/CMakeLists.txt index aa428fce56a59..bfea8f7e39f91 100644 --- a/clang-tools-extra/clang-tidy/objc/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/objc/CMakeLists.txt @@ -31,3 +31,9 @@ clang_target_link_libraries(clangTidyObjCModule clangBasic clangLex ) + + set_target_properties(obj.clangTidyObjCModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp index 951cbc52c9a99..b4b61003a650f 100644 --- a/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp +++ b/clang-tools-extra/clang-tidy/objc/SuperSelfCheck.cpp @@ -36,7 +36,7 @@ AST_MATCHER(ObjCMethodDecl, isInitializer) { /// \c Base. /// /// Example matches implementation declarations for X. -/// (matcher = objcImplementationDecl(hasInterface(hasName("X")))) +/// (matcher = objcImplementationDecl(hasInterface2(hasName("X")))) /// \code /// @interface X /// @end @@ -47,7 +47,7 @@ AST_MATCHER(ObjCMethodDecl, isInitializer) { /// @implementation Y /// @end /// \endcode -AST_MATCHER_P(ObjCImplementationDecl, hasInterface, +AST_MATCHER_P(ObjCImplementationDecl, hasInterface2, ast_matchers::internal::Matcher<ObjCInterfaceDecl>, Base) { const ObjCInterfaceDecl *InterfaceDecl = Node.getClassInterface(); return Base.matches(*InterfaceDecl, Finder, Builder); @@ -76,7 +76,7 @@ void SuperSelfCheck::registerMatchers(MatchFinder *Finder) { objcMessageExpr(hasSelector("self"), isMessagingSuperInstance(), hasAncestor(objcMethodDecl( isInitializer(), - hasDeclContext(objcImplementationDecl(hasInterface( + hasDeclContext(objcImplementationDecl(hasInterface2( isDerivedFrom(hasName("NSObject")))))))) .bind("message"), this); diff --git a/clang-tools-extra/clang-tidy/openmp/CMakeLists.txt b/clang-tools-extra/clang-tidy/openmp/CMakeLists.txt index 4ef61f88c0509..b5c2c9b2af021 100644 --- a/clang-tools-extra/clang-tidy/openmp/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/openmp/CMakeLists.txt @@ -22,3 +22,9 @@ clang_target_link_libraries(clangTidyOpenMPModule clangASTMatchers clangBasic ) + + set_target_properties(obj.clangTidyOpenMPModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt index 81128ff086021..04ff1ba89dbc8 100644 --- a/clang-tools-extra/clang-tidy/performance/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/performance/CMakeLists.txt @@ -43,3 +43,9 @@ clang_target_link_libraries(clangTidyPerformanceModule clangBasic clangLex ) + + set_target_properties(obj.clangTidyPerformanceModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp index 9beb185cba929..8c38bad593a37 100644 --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -232,7 +232,7 @@ UnnecessaryCopyInitialization::UnnecessaryCopyInitialization( Options.get("ExcludedContainerTypes", ""))) {} void UnnecessaryCopyInitialization::registerMatchers(MatchFinder *Finder) { - auto LocalVarCopiedFrom = [this](const internal::Matcher<Expr> &CopyCtorArg) { + auto LocalVarCopiedFrom = [this](const auto &CopyCtorArg) { return compoundStmt( forEachDescendant( declStmt( diff --git a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt index 01a86d686daa7..af9704c506431 100644 --- a/clang-tools-extra/clang-tidy/portability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/portability/CMakeLists.txt @@ -27,3 +27,9 @@ clang_target_link_libraries(clangTidyPortabilityModule clangLex clangTooling ) + + set_target_properties(obj.clangTidyPortabilityModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index 41065fc8e8785..fa96ecc7c1584 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -68,6 +68,12 @@ add_clang_library(clangTidyReadabilityModule ClangDriverOptions ) + set_target_properties(obj.clangTidyReadabilityModule PROPERTIES + UNITY_BUILD ON + UNITY_BUILD_MODE BATCH + UNITY_BUILD_BATCH_SIZE 12 + ) + clang_target_link_libraries(clangTidyReadabilityModule PRIVATE clangAnalysis @@ -77,3 +83,4 @@ clang_target_link_libraries(clangTidyReadabilityModule clangLex clangTooling ) + diff --git a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp index 1284df6bd99cf..b3227cd5aaa07 100644 --- a/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp +++ b/clang-tools-extra/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp @@ -18,6 +18,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { + namespace { AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); } AST_MATCHER(CXXMethodDecl, hasTrivialBody) { return Node.hasTrivialBody(); } @@ -74,6 +75,8 @@ AST_MATCHER(CXXMethodDecl, usesThis) { return UsageOfThis.Used; } +} + void ConvertMemberFunctionsToStatic::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( cxxMethodDecl( diff --git a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp index 759cdd44fd658..48ee35fb9bfa2 100644 --- a/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/FunctionCognitiveComplexityCheck.cpp @@ -202,9 +202,9 @@ void CognitiveComplexity::account(SourceLocation Loc, unsigned short Nesting, Total += Increase; } -class FunctionASTVisitor final - : public RecursiveASTVisitor<FunctionASTVisitor> { - using Base = RecursiveASTVisitor<FunctionASTVisitor>; +class FunctionASTVisitor2 final + : public RecursiveASTVisitor<FunctionASTVisitor2> { + using Base = RecursiveASTVisitor<FunctionASTVisitor2>; // If set to true, macros are ignored during analysis. const bool IgnoreMacros; @@ -219,7 +219,7 @@ class FunctionASTVisitor final std::stack<OBO, SmallVector<OBO, 4>> BinaryOperatorsStack; public: - explicit FunctionASTVisitor(const bool IgnoreMacros) + explicit FunctionASTVisitor2(const bool IgnoreMacros) : IgnoreMacros(IgnoreMacros) {} bool traverseStmtWithIncreasedNestingLevel(Stmt *Node) { @@ -453,7 +453,7 @@ class FunctionASTVisitor final // The parameter MainAnalyzedFunction is needed to differentiate between the // cases where TraverseDecl() is the entry point from // FunctionCognitiveComplexityCheck::check() and the cases where it was called - // from the FunctionASTVisitor itself. Explanation: if we get a function + // from the FunctionASTVisitor2 itself. Explanation: if we get a function // definition (e.g. constructor, destructor, method), the Cognitive Complexity // specification states that the Nesting level shall be increased. But if this // function is the entry point, then the Nesting level should not be @@ -515,7 +515,7 @@ void FunctionCognitiveComplexityCheck::registerMatchers(MatchFinder *Finder) { void FunctionCognitiveComplexityCheck::check( const MatchFinder::MatchResult &Result) { - FunctionASTVisitor Visitor(IgnoreMacros); + FunctionASTVisitor2 Visitor(IgnoreMacros); SourceLocation Loc; const auto *TheDecl = Result.Nodes.getNodeAs<FunctionDecl>("func"); diff --git a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp index d42fcba70e81b..a4f3acb66601f 100644 --- a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp @@ -17,6 +17,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { +namespace { AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); } AST_MATCHER(CXXMethodDecl, hasTrivialBody) { return Node.hasTrivialBody(); } @@ -46,7 +47,7 @@ AST_MATCHER_P(CXXMethodDecl, hasCanonicalDecl, ast_matchers::internal::Matcher<CXXMethodDecl>, InnerMatcher) { return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder); } - +} enum UsageKind { Unused, Const, NonConst }; class FindUsageOfThis : public RecursiveASTVisitor<FindUsageOfThis> { @@ -205,6 +206,7 @@ class FindUsageOfThis : public RecursiveASTVisitor<FindUsageOfThis> { } }; +namespace { AST_MATCHER(CXXMethodDecl, usesThisAsConst) { FindUsageOfThis UsageOfThis(Finder->getASTContext()); @@ -214,6 +216,8 @@ AST_MATCHER(CXXMethodDecl, usesThisAsConst) { return UsageOfThis.Usage == Const; } +} + void MakeMemberFunctionConstCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( traverse( diff --git a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp index 7850a6f29995f..8dc2ad84c89a4 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp @@ -15,10 +15,13 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { +namespace { AST_MATCHER(FunctionDecl, doesDeclarationForceExternallyVisibleDefinition) { return Node.doesDeclarationForceExternallyVisibleDefinition(); } +} + RedundantDeclarationCheck::RedundantDeclarationCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), diff --git a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp index 8837ac16e8828..213f4d2c5eba1 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantSmartptrGetCheck.cpp @@ -15,7 +15,7 @@ using namespace clang::ast_matchers; namespace clang::tidy::readability { namespace { -internal::Matcher<Expr> callToGet(const internal::Matcher<Decl> &OnClass) { +clang::ast_matchers::internal::Matcher<Expr> callToGet(const clang::ast_matchers::internal::Matcher<Decl> &OnClass) { return expr( anyOf(cxxMemberCallExpr( on(expr(anyOf(hasType(OnClass), @@ -43,7 +43,7 @@ internal::Matcher<Expr> callToGet(const internal::Matcher<Decl> &OnClass) { .bind("redundant_get"); } -internal::Matcher<Decl> knownSmartptr() { +clang::ast_matchers::internal::Matcher<Decl> knownSmartptr() { return recordDecl(hasAnyName("::std::unique_ptr", "::std::shared_ptr")); } diff --git a/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp b/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp index 587ae8ea30580..ba7ffb31fd6de 100644 --- a/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReferenceToConstructedTemporaryCheck.cpp @@ -20,7 +20,7 @@ namespace { // Predicate structure to check if lifetime of temporary is not extended by // ValueDecl pointed out by ID struct NotExtendedByDeclBoundToPredicate { - bool operator()(const internal::BoundNodesMap &Nodes) const { + bool operator()(const clang::ast_matchers::internal::BoundNodesMap &Nodes) const { const auto *Other = Nodes.getNodeAs<ValueDecl>(ID); if (!Other) return true; >From 7116f13a21f0246ca652db2ffdd775b1dcb183a4 Mon Sep 17 00:00:00 2001 From: Piotr Zegar <piotr.ze...@nokia.com> Date: Sun, 24 Mar 2024 18:39:54 +0000 Subject: [PATCH 2/6] [clang-tidy] Added bugprone-exception-rethrow check Identifies problematic exception rethrowing, especially with caught exception variables or empty throw statements outside catch blocks. Closes #71292 --- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt | 1 + .../bugprone/ExceptionRethrowCheck.cpp | 50 ++++++++++++++ .../bugprone/ExceptionRethrowCheck.h | 37 ++++++++++ clang-tools-extra/docs/ReleaseNotes.rst | 6 ++ .../checks/bugprone/exception-rethrow.rst | 68 +++++++++++++++++++ .../docs/clang-tidy/checks/list.rst | 1 + .../checkers/bugprone/exception-rethrow.cpp | 60 ++++++++++++++++ 8 files changed, 226 insertions(+) create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 1b92d2e60cc17..7466d3f2e4fc2 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -26,6 +26,7 @@ #include "EasilySwappableParametersCheck.h" #include "EmptyCatchCheck.h" #include "ExceptionEscapeCheck.h" +#include "ExceptionRethrowCheck.h" #include "FoldInitTypeCheck.h" #include "ForwardDeclarationNamespaceCheck.h" #include "ForwardingReferenceOverloadCheck.h" @@ -127,6 +128,8 @@ class BugproneModule : public ClangTidyModule { CheckFactories.registerCheck<EmptyCatchCheck>("bugprone-empty-catch"); CheckFactories.registerCheck<ExceptionEscapeCheck>( "bugprone-exception-escape"); + CheckFactories.registerCheck<ExceptionRethrowCheck>( + "bugprone-exception-rethrow"); CheckFactories.registerCheck<FoldInitTypeCheck>("bugprone-fold-init-type"); CheckFactories.registerCheck<ForwardDeclarationNamespaceCheck>( "bugprone-forward-declaration-namespace"); diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index c0f5ea69e9279..45a3983cf713f 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangTidyBugproneModule EasilySwappableParametersCheck.cpp EmptyCatchCheck.cpp ExceptionEscapeCheck.cpp + ExceptionRethrowCheck.cpp FoldInitTypeCheck.cpp ForwardDeclarationNamespaceCheck.cpp ForwardingReferenceOverloadCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp new file mode 100644 index 0000000000000..4855ccc2724a9 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -0,0 +1,50 @@ +//===--- ExceptionRethrowCheck.cpp - clang-tidy ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "ExceptionRethrowCheck.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } +} // namespace + +void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + cxxThrowExpr(unless(isExpansionInSystemHeader()), + anyOf(unless(has(expr())), + has(declRefExpr(to(varDecl(isExceptionVariable()))))), + optionally(hasAncestor(cxxCatchStmt().bind("catch")))) + .bind("throw"), + this); +} + +void ExceptionRethrowCheck::check(const MatchFinder::MatchResult &Result) { + const auto *MatchedThrow = Result.Nodes.getNodeAs<CXXThrowExpr>("throw"); + + if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { + diag(MatchedThrow->getThrowLoc(), + "throwing a copy of the caught %0 exception, remove the argument to " + "throw the original exception object") + << ThrownObject->getType().getNonReferenceType(); + return; + } + + const bool HasCatchAnsestor = + Result.Nodes.getNodeAs<Stmt>("catch") != nullptr; + if (!HasCatchAnsestor) { + diag(MatchedThrow->getThrowLoc(), + "empty 'throw' outside a catch block without an exception can trigger " + "'std::terminate'"); + } +} + +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h new file mode 100644 index 0000000000000..bbb30f779cf25 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h @@ -0,0 +1,37 @@ +//===--- ExceptionRethrowCheck.h - clang-tidy -------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTIONRETHROWCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTIONRETHROWCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::bugprone { + +/// Identifies problematic exception rethrowing, especially with caught +/// exception variables or empty throw statements outside catch blocks. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/exception-rethrow.html +class ExceptionRethrowCheck : public ClangTidyCheck { +public: + ExceptionRethrowCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + std::optional<TraversalKind> getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus && LangOpts.CXXExceptions; + } +}; + +} // namespace clang::tidy::bugprone + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTIONRETHROWCHECK_H diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 3038d2b125f20..776edb1da2ad0 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -119,6 +119,12 @@ New checks Detects error-prone Curiously Recurring Template Pattern usage, when the CRTP can be constructed outside itself and the derived class. +- New :doc:`bugprone-exception-rethrow + <clang-tidy/checks/bugprone/exception-rethrow>` check. + + Identifies problematic exception rethrowing, especially with caught exception + variables or empty throw statements outside catch blocks. + - New :doc:`bugprone-return-const-ref-from-parameter <clang-tidy/checks/bugprone/return-const-ref-from-parameter>` check. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst new file mode 100644 index 0000000000000..981dfff852d58 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst @@ -0,0 +1,68 @@ +.. title:: clang-tidy - bugprone-exception-rethrow + +bugprone-exception-rethrow +========================== + +Identifies problematic exception rethrowing, especially with caught exception +variables or empty throw statements outside catch blocks. + +In C++ exception handling, a common pitfall occurs when developers rethrow +caught exceptions within catch blocks by directly passing the caught exception +variable to the ``throw`` statement. While this approach can propagate +exceptions to higher levels of the program, it often leads to code that is less +clear and more error-prone. Rethrowing caught exceptions with the same exception +object within catch blocks can obscure the original context of the exception and +make it challenging to trace program flow. Additionally, this method can +introduce issues such as exception object slicing and performance overhead due +to the invocation of the copy constructor. + +.. code-block:: c++ + + try { + // Code that may throw an exception + } catch (const std::exception& e) { + throw e; // Bad + } + +To prevent these issues, it is advisable to utilize ``throw;`` statements to +rethrow the original exception object for currently handled exceptions. + +.. code-block:: c++ + + try { + // Code that may throw an exception + } catch (const std::exception& e) { + throw; // Good + } + +However, when empty throw statement is used outside of a catch block, it +will result in a call to ``std::terminate()``, which abruptly terminates the +application. This behavior can lead to abnormal termination of the program and +is often unintended. Such occurrences may indicate errors or oversights in the +exception handling logic, and it is essential to avoid empty throw statements +outside catch blocks to prevent unintended program termination. + +.. code-block:: c++ + + void foo() { + // std::terminate will be called because there is no exception to rethrow + throw; + } + + int main() { + try { + foo(); + } catch(...) { + return 1; + } + return 0; + } + +Above program will be terminated with: + +.. code:: text + + terminate called without an active exception + Aborted (core dumped) + + diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 49747ff896ba5..79e998a7d99c2 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -92,6 +92,7 @@ Clang-Tidy Checks :doc:`bugprone-easily-swappable-parameters <bugprone/easily-swappable-parameters>`, :doc:`bugprone-empty-catch <bugprone/empty-catch>`, :doc:`bugprone-exception-escape <bugprone/exception-escape>`, + :doc:`bugprone-exception-rethrow <bugprone/exception-rethrow>`, :doc:`bugprone-fold-init-type <bugprone/fold-init-type>`, :doc:`bugprone-forward-declaration-namespace <bugprone/forward-declaration-namespace>`, :doc:`bugprone-forwarding-reference-overload <bugprone/forwarding-reference-overload>`, diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp new file mode 100644 index 0000000000000..5e7ba03652393 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp @@ -0,0 +1,60 @@ +// RUN: %check_clang_tidy %s bugprone-exception-rethrow %t -- -- -fexceptions + +struct exception {}; + +void correct() { + try { + throw exception(); + } catch(const exception &) { + throw; + } +} + +void correct2() { + try { + throw exception(); + } catch(const exception &e) { + try { + throw exception(); + } catch(...) {} + } +} + +void not_correct() { + try { + throw exception(); + } catch(const exception &e) { + throw e; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: throwing a copy of the caught 'exception' exception, remove the argument to throw the original exception object [bugprone-exception-rethrow] + } +} + +void not_correct2() { + try { + throw 5; + } catch(const int &e) { + throw e; +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: throwing a copy of the caught 'int' exception, remove the argument to throw the original exception object [bugprone-exception-rethrow] + } +} + +void rethrow_not_correct() { + throw; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: empty 'throw' outside a catch block without an exception can trigger 'std::terminate' [bugprone-exception-rethrow] +} + +void rethrow_not_correct2() { + try { + throw; +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: empty 'throw' outside a catch block without an exception can trigger 'std::terminate' [bugprone-exception-rethrow] + } catch(...) { + } +} + +void rethrow_correct() { + try { + throw 5; + } catch(...) { + throw; + } +} >From 2726eca89317e095dd21735da8539050f9e2441a Mon Sep 17 00:00:00 2001 From: Piotr Zegar <pitor.ze...@nokia.com> Date: Sun, 24 Mar 2024 18:43:47 +0000 Subject: [PATCH 3/6] Fix code -> code-block in doc --- .../docs/clang-tidy/checks/bugprone/exception-rethrow.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst index 981dfff852d58..68be515297bc5 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst @@ -60,7 +60,7 @@ outside catch blocks to prevent unintended program termination. Above program will be terminated with: -.. code:: text +.. code-block:: text terminate called without an active exception Aborted (core dumped) >From 952b2b4d6eb3872f99beb49b06729604d77b4153 Mon Sep 17 00:00:00 2001 From: Piotr Zegar <piotr.ze...@nokia.com> Date: Sun, 31 Mar 2024 12:12:43 +0000 Subject: [PATCH 4/6] Fixes for review --- .../bugprone/ExceptionRethrowCheck.cpp | 23 ++++++----- .../bugprone/ExceptionRethrowCheck.h | 4 +- .../checks/bugprone/exception-rethrow.rst | 1 - .../checkers/bugprone/exception-rethrow.cpp | 38 ++++++++++++++++++- 4 files changed, 52 insertions(+), 14 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp index 4855ccc2724a9..3e327606ee562 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -8,20 +8,26 @@ #include "ExceptionRethrowCheck.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" using namespace clang::ast_matchers; namespace clang::tidy::bugprone { -namespace { -AST_MATCHER(VarDecl, isExceptionVariable) { return Node.isExceptionVariable(); } -} // namespace - void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { + + auto RefToExceptionVariable = declRefExpr(to(varDecl(isExceptionVariable()))); + auto StdMoveCall = callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), hasArgument(0, RefToExceptionVariable)); + auto CopyOrMoveConstruction = cxxConstructExpr(argumentCountIs(1), hasDeclaration(cxxConstructorDecl(anyOf(isCopyConstructor(), isMoveConstructor()))), hasArgument(0, anyOf(RefToExceptionVariable, StdMoveCall))); + auto FunctionCast = cxxFunctionalCastExpr( hasSourceExpression(anyOf(RefToExceptionVariable, StdMoveCall))); + Finder->addMatcher( cxxThrowExpr(unless(isExpansionInSystemHeader()), anyOf(unless(has(expr())), - has(declRefExpr(to(varDecl(isExceptionVariable()))))), + has(RefToExceptionVariable), + has(StdMoveCall), + has(CopyOrMoveConstruction), + has(FunctionCast)), optionally(hasAncestor(cxxCatchStmt().bind("catch")))) .bind("throw"), this); @@ -38,12 +44,11 @@ void ExceptionRethrowCheck::check(const MatchFinder::MatchResult &Result) { return; } - const bool HasCatchAnsestor = + const bool HasCatchAncestor = Result.Nodes.getNodeAs<Stmt>("catch") != nullptr; - if (!HasCatchAnsestor) { + if (!HasCatchAncestor) { diag(MatchedThrow->getThrowLoc(), - "empty 'throw' outside a catch block without an exception can trigger " - "'std::terminate'"); + "empty 'throw' outside a catch block with no operand triggers 'std::terminate()'"); } } diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h index bbb30f779cf25..efe9aad80d13d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTIONRETHROWCHECK_H -#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTIONRETHROWCHECK_H +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTION_RETHROW_CHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTION_RETHROW_CHECK_H #include "../ClangTidyCheck.h" diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst index 68be515297bc5..677537094e5f6 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst @@ -65,4 +65,3 @@ Above program will be terminated with: terminate called without an active exception Aborted (core dumped) - diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp index 5e7ba03652393..a5732d9b2f44b 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp @@ -2,6 +2,13 @@ struct exception {}; +namespace std { + template <class T> + T&& move(T &x) { + return static_cast<T&&>(x); + } +} + void correct() { try { throw exception(); @@ -30,6 +37,33 @@ void not_correct() { } void not_correct2() { + try { + throw exception(); + } catch(const exception &e) { + throw (e); +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: throwing a copy of the caught 'exception' exception, remove the argument to throw the original exception object [bugprone-exception-rethrow] + } +} + +void not_correct3() { + try { + throw exception(); + } catch(const exception &e) { + throw exception(e); +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: throwing a copy of the caught 'exception' exception, remove the argument to throw the original exception object [bugprone-exception-rethrow] + } +} + +void not_correct4() { + try { + throw exception(); + } catch(exception &e) { + throw std::move(e); +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: throwing a copy of the caught 'exception' exception, remove the argument to throw the original exception object [bugprone-exception-rethrow] + } +} + +void not_correct5() { try { throw 5; } catch(const int &e) { @@ -40,13 +74,13 @@ void not_correct2() { void rethrow_not_correct() { throw; -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: empty 'throw' outside a catch block without an exception can trigger 'std::terminate' [bugprone-exception-rethrow] +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: empty 'throw' outside a catch block with no operand triggers 'std::terminate()' [bugprone-exception-rethrow] } void rethrow_not_correct2() { try { throw; -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: empty 'throw' outside a catch block without an exception can trigger 'std::terminate' [bugprone-exception-rethrow] +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: empty 'throw' outside a catch block with no operand triggers 'std::terminate()' [bugprone-exception-rethrow] } catch(...) { } } >From 56a551a0a5e9b2fac7eb0318f1124d384fa80873 Mon Sep 17 00:00:00 2001 From: Piotr Zegar <piotr.ze...@nokia.com> Date: Sun, 28 Apr 2024 16:46:08 +0000 Subject: [PATCH 5/6] Add support for copy constructors, std::move, and so on --- .../bugprone/ExceptionRethrowCheck.cpp | 47 ++++++++++++------- .../checkers/bugprone/exception-rethrow.cpp | 9 ++++ 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp index 3e327606ee562..55f94306f395e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionRethrowCheck.cpp @@ -17,26 +17,39 @@ namespace clang::tidy::bugprone { void ExceptionRethrowCheck::registerMatchers(MatchFinder *Finder) { auto RefToExceptionVariable = declRefExpr(to(varDecl(isExceptionVariable()))); - auto StdMoveCall = callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), hasArgument(0, RefToExceptionVariable)); - auto CopyOrMoveConstruction = cxxConstructExpr(argumentCountIs(1), hasDeclaration(cxxConstructorDecl(anyOf(isCopyConstructor(), isMoveConstructor()))), hasArgument(0, anyOf(RefToExceptionVariable, StdMoveCall))); - auto FunctionCast = cxxFunctionalCastExpr( hasSourceExpression(anyOf(RefToExceptionVariable, StdMoveCall))); + auto StdMoveCall = + callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), + hasArgument(0, RefToExceptionVariable)); + auto CopyOrMoveConstruction = cxxConstructExpr( + argumentCountIs(1), + traverse(TK_AsIs, hasDeclaration(cxxConstructorDecl( + anyOf(isCopyConstructor(), isMoveConstructor())))), + hasArgument(0, anyOf(RefToExceptionVariable, StdMoveCall))); + auto HasEmptyThrowExprDescendant = + hasDescendant(cxxThrowExpr(equalsBoundNode("empty-throw"))); + + Finder->addMatcher( + cxxThrowExpr( + unless(isExpansionInSystemHeader()), unless(has(expr())), + expr().bind("empty-throw"), + anyOf(unless(hasAncestor(cxxCatchStmt())), + hasAncestor(cxxCatchStmt(anyOf( + hasDescendant(functionDecl(HasEmptyThrowExprDescendant)), + hasDescendant(lambdaExpr(HasEmptyThrowExprDescendant))))))), + this); Finder->addMatcher( cxxThrowExpr(unless(isExpansionInSystemHeader()), - anyOf(unless(has(expr())), - has(RefToExceptionVariable), - has(StdMoveCall), - has(CopyOrMoveConstruction), - has(FunctionCast)), - optionally(hasAncestor(cxxCatchStmt().bind("catch")))) + has(expr(anyOf(RefToExceptionVariable, StdMoveCall, + CopyOrMoveConstruction)))) .bind("throw"), this); } void ExceptionRethrowCheck::check(const MatchFinder::MatchResult &Result) { - const auto *MatchedThrow = Result.Nodes.getNodeAs<CXXThrowExpr>("throw"); - - if (const Expr *ThrownObject = MatchedThrow->getSubExpr()) { + if (const auto *MatchedThrow = + Result.Nodes.getNodeAs<CXXThrowExpr>("throw")) { + const Expr *ThrownObject = MatchedThrow->getSubExpr(); diag(MatchedThrow->getThrowLoc(), "throwing a copy of the caught %0 exception, remove the argument to " "throw the original exception object") @@ -44,11 +57,11 @@ void ExceptionRethrowCheck::check(const MatchFinder::MatchResult &Result) { return; } - const bool HasCatchAncestor = - Result.Nodes.getNodeAs<Stmt>("catch") != nullptr; - if (!HasCatchAncestor) { - diag(MatchedThrow->getThrowLoc(), - "empty 'throw' outside a catch block with no operand triggers 'std::terminate()'"); + if (const auto *MatchedEmptyThrow = + Result.Nodes.getNodeAs<CXXThrowExpr>("empty-throw")) { + diag(MatchedEmptyThrow->getThrowLoc(), + "empty 'throw' outside a catch block with no operand triggers " + "'std::terminate()'"); } } diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp index a5732d9b2f44b..2914d2e7452b8 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp @@ -92,3 +92,12 @@ void rethrow_correct() { throw; } } + +void rethrow_in_lambda() { + try { + throw 5; + } catch(...) { + auto lambda = [] { throw; }; +// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: empty 'throw' outside a catch block with no operand triggers 'std::terminate()' [bugprone-exception-rethrow] + } +} >From 77544d0e5ddbca3f147cf5886ba00a23f56bc4b0 Mon Sep 17 00:00:00 2001 From: Piotr Zegar <piotr.ze...@nokia.com> Date: Tue, 21 May 2024 22:18:43 +0200 Subject: [PATCH 6/6] Fix in doc --- .../checks/bugprone/exception-rethrow.rst | 31 +++++++++++++------ .../checkers/bugprone/exception-rethrow.cpp | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst index 677537094e5f6..c694ddcf610f6 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/exception-rethrow.rst @@ -21,7 +21,20 @@ to the invocation of the copy constructor. try { // Code that may throw an exception } catch (const std::exception& e) { - throw e; // Bad + throw e; // Bad, 'e' is copied + } + +.. code-block:: c++ + + class derived_exception : public std::exception { ... }; + + void throwDerived() { throw derived_exception{}; } + + try { + throwDerived(); + } catch (const std::exception& e) { + throw e; // Bad, exception slicing occurs when 'derived_exception' is + // being rethrown as 'std::exception' } To prevent these issues, it is advisable to utilize ``throw;`` statements to @@ -31,16 +44,16 @@ rethrow the original exception object for currently handled exceptions. try { // Code that may throw an exception - } catch (const std::exception& e) { + } catch (const std::exception&) { throw; // Good } -However, when empty throw statement is used outside of a catch block, it -will result in a call to ``std::terminate()``, which abruptly terminates the -application. This behavior can lead to abnormal termination of the program and -is often unintended. Such occurrences may indicate errors or oversights in the -exception handling logic, and it is essential to avoid empty throw statements -outside catch blocks to prevent unintended program termination. +However, when an empty throw statement is used outside a catch block, it +results in a call to ``std::terminate()``, which abruptly terminates the +application. This behavior can lead to the abnormal termination of the +program and is often unintended. Such occurrences may indicate errors or +oversights in the exception handling logic, and it is essential to avoid empty +throw statements outside catch blocks to prevent unintended program termination. .. code-block:: c++ @@ -58,7 +71,7 @@ outside catch blocks to prevent unintended program termination. return 0; } -Above program will be terminated with: +The above program will be terminated with: .. code-block:: text diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp index 2914d2e7452b8..de2f41d04ae50 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/exception-rethrow.cpp @@ -4,7 +4,7 @@ struct exception {}; namespace std { template <class T> - T&& move(T &x) { + T&& move(T &&x) { return static_cast<T&&>(x); } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits