diff options
Diffstat (limited to 'clang-tools-extra')
3 files changed, 30 insertions, 3 deletions
diff --git a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp index a5e54c0a182..416cf3fd874 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ExceptionEscapeCheck.cpp @@ -187,12 +187,12 @@ void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { void ExceptionEscapeCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( - functionDecl(allOf(throws(unless(isIgnored(IgnoredExceptions))), - anyOf(isNoThrow(), cxxDestructorDecl(), + functionDecl(allOf(anyOf(isNoThrow(), cxxDestructorDecl(), cxxConstructorDecl(isMoveConstructor()), cxxMethodDecl(isMoveAssignmentOperator()), hasName("main"), hasName("swap"), - isEnabled(FunctionsThatShouldNotThrow)))) + isEnabled(FunctionsThatShouldNotThrow)), + throws(unless(isIgnored(IgnoredExceptions))))) .bind("thrower"), this); } diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-exception-escape.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-exception-escape.rst index 3037f5e3ea5..e9653a7e5d5 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone-exception-escape.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-exception-escape.rst @@ -21,6 +21,8 @@ are always possible to implement in a non throwing way. Non throwing ``swap()`` operations are also used to create move operations. A throwing ``main()`` function also results in unexpected termination. +WARNING! This check may be expensive on large source files. + Options ------- diff --git a/clang-tools-extra/test/clang-tidy/bugprone-exception-escape.cpp b/clang-tools-extra/test/clang-tidy/bugprone-exception-escape.cpp index af2c23d48e2..eba14bfcf03 100644 --- a/clang-tools-extra/test/clang-tidy/bugprone-exception-escape.cpp +++ b/clang-tools-extra/test/clang-tidy/bugprone-exception-escape.cpp @@ -258,6 +258,31 @@ void this_counts(int n) noexcept { throw ignored1(); } +void thrower(int n) { + throw n; +} + +int directly_recursive(int n) noexcept { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'directly_recursive' which should not throw exceptions + if (n == 0) + thrower(n); + return directly_recursive(n); +} + +int indirectly_recursive(int n) noexcept; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'indirectly_recursive' which should not throw exceptions + +int recursion_helper(int n) { + indirectly_recursive(n); +} + +int indirectly_recursive(int n) noexcept { + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'indirectly_recursive' which should not throw exceptions + if (n == 0) + thrower(n); + return recursion_helper(n); +} + int main() { // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in function 'main' which should not throw exceptions throw 1; |