[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