From 7ba0a8daae10edc2bf03149832655eccbb2e2304 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Thu, 29 Nov 2018 21:27:29 +0000 Subject: Merging r344444 and r344445: ------------------------------------------------------------------------ r344444 | baloghadamsoftware | 2018-10-13 03:34:52 -0700 (Sat, 13 Oct 2018) | 11 lines [clang-tidy] Optimize query in bugprone-exception-escape Checking whether a functions throws indirectly may be very expensive because it needs to visit its whole call graph. Therefore we should first check whether the function is forbidden to throw and only check whether it throws afterward. This also seems to solve bug https://bugs.llvm.org/show_bug.cgi?id=39167 where the execution time is so long that it seems to hang. Differential Revision: https://reviews.llvm.org/D53187 ------------------------------------------------------------------------ ------------------------------------------------------------------------ r344445 | baloghadamsoftware | 2018-10-13 04:17:59 -0700 (Sat, 13 Oct 2018) | 3 lines [clang-tidy] Fix for typos in the tests for `bugprone-exception-escape` ------------------------------------------------------------------------ --- .../clang-tidy/bugprone/ExceptionEscapeCheck.cpp | 6 +++--- .../checks/bugprone-exception-escape.rst | 2 ++ .../test/clang-tidy/bugprone-exception-escape.cpp | 25 ++++++++++++++++++++++ 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; -- cgit v1.2.3