[clang-tools-extra] [clang-tidy] Added bugprone-exception-rethrow check (PR #86448)

Piotr Zegar via cfe-commits cfe-commits at lists.llvm.org
Tue May 21 13:33:18 PDT 2024


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 <me at 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.zegar at 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.zegar at 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.zegar at 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.zegar at 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.zegar at 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);
   }
 }



More information about the cfe-commits mailing list