Fix #75686: add iter_swap and iter_move to the matched name (#76117)

Added support for iter_swap, iter_move in bugprone-exception-escape 
and performance-noexcept-swap checks.

Fixes  #75686
This commit is contained in:
Da-Viper 2024-01-14 09:48:47 +00:00 committed by GitHub
parent d3ac676ea4
commit 356c2c2399
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 12 deletions

View File

@ -28,6 +28,10 @@ AST_MATCHER(FunctionDecl, isExplicitThrow) {
Node.getExceptionSpecSourceRange().isValid();
}
AST_MATCHER(FunctionDecl, hasAtLeastOneParameter) {
return Node.getNumParams() > 0;
}
} // namespace
ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name,
@ -58,14 +62,16 @@ void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void ExceptionEscapeCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
functionDecl(isDefinition(),
anyOf(isNoThrow(),
allOf(anyOf(cxxDestructorDecl(),
cxxConstructorDecl(isMoveConstructor()),
cxxMethodDecl(isMoveAssignmentOperator()),
isMain(), hasName("swap")),
unless(isExplicitThrow())),
isEnabled(FunctionsThatShouldNotThrow)))
functionDecl(
isDefinition(),
anyOf(isNoThrow(),
allOf(anyOf(cxxDestructorDecl(),
cxxConstructorDecl(isMoveConstructor()),
cxxMethodDecl(isMoveAssignmentOperator()), isMain(),
allOf(hasAnyName("swap", "iter_swap", "iter_move"),
hasAtLeastOneParameter())),
unless(isExplicitThrow())),
isEnabled(FunctionsThatShouldNotThrow)))
.bind("thrower"),
this);
}

View File

@ -39,7 +39,8 @@ void NoexceptSwapCheck::registerMatchers(MatchFinder *Finder) {
.bind("type"))))),
hasParameter(1, hasType(qualType(hasCanonicalType(
qualType(equalsBoundNode("type")))))));
Finder->addMatcher(functionDecl(unless(isDeleted()), hasName("swap"),
Finder->addMatcher(functionDecl(unless(isDeleted()),
hasAnyName("swap", "iter_swap"),
anyOf(MethodMatcher, FunctionMatcher))
.bind(BindFuncDeclName),
this);

View File

@ -260,6 +260,10 @@ Changes in existing checks
casting during type conversions at variable initialization, now with improved
compatibility for C++17 and later versions.
- Improved :doc:`bugprone-exception-escape
<clang-tidy/checks/bugprone/exception-escape>` check by extending the default
check function names to include ``iter_swap`` and ``iter_move``.
- Improved :doc:`bugprone-implicit-widening-of-multiplication-result
<clang-tidy/checks/bugprone/implicit-widening-of-multiplication-result>` check
to correctly emit fixes.
@ -445,7 +449,8 @@ Changes in existing checks
- Improved :doc:`performance-noexcept-swap
<clang-tidy/checks/performance/noexcept-swap>` check to enforce a stricter
match with the swap function signature and better handling of condition
noexcept expressions, eliminating false-positives.
noexcept expressions, eliminating false-positives. ``iter_swap`` function name
is checked by default.
- Improved :doc:`readability-braces-around-statements
<clang-tidy/checks/readability/braces-around-statements>` check to

View File

@ -11,6 +11,8 @@ should not. The functions which should not throw exceptions are the following:
* Move assignment operators
* The ``main()`` functions
* ``swap()`` functions
* ``iter_swap()`` functions
* ``iter_move()`` functions
* Functions marked with ``throw()`` or ``noexcept``
* Other functions given as option

View File

@ -3,11 +3,11 @@
performance-noexcept-swap
=========================
The check flags user-defined swap functions not marked with ``noexcept`` or
The check flags user-defined swap and iter_swap functions not marked with ``noexcept`` or
marked with ``noexcept(expr)`` where ``expr`` evaluates to ``false``
(but is not a ``false`` literal itself).
When a swap function is marked as ``noexcept``, it assures the compiler that
When a swap or iter_swap function is marked as ``noexcept``, it assures the compiler that
no exceptions will be thrown during the swapping of two objects, which allows
the compiler to perform certain optimizations such as omitting exception
handling code.

View File

@ -586,6 +586,16 @@ void swap(int&, int&) {
throw 1;
}
void iter_swap(int&, int&) {
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'iter_swap' which should not throw exceptions
throw 1;
}
void iter_move(int&) {
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: an exception may be thrown in function 'iter_move' which should not throw exceptions
throw 1;
}
namespace std {
class bad_alloc {};
}

View File

@ -32,6 +32,10 @@ void swap(A &, A &);
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: swap functions should be marked noexcept [performance-noexcept-swap]
// CHECK-FIXES: void swap(A &, A &) noexcept ;
void iter_swap(A &, A &);
// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: swap functions should be marked noexcept [performance-noexcept-swap]
// CHECK-FIXES: void iter_swap(A &, A &) noexcept ;
struct B {
static constexpr bool kFalse = false;
void swap(B &) noexcept(kFalse);