diff --git a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp index 1252b2f23805a..243fe47c2036b 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp @@ -11,6 +11,8 @@ #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/OperatorKinds.h" using namespace clang::ast_matchers; using namespace clang::ast_matchers::internal; @@ -28,6 +30,11 @@ AST_MATCHER_P(FunctionDecl, isInstantiatedFrom, Matcher, return InnerMatcher.matches(InstantiatedFrom ? *InstantiatedFrom : Node, Finder, Builder); } + +AST_MATCHER_P(CXXMethodDecl, isOperatorOverloading, + llvm::SmallVector, Kinds) { + return llvm::is_contained(Kinds, Node.getOverloadedOperator()); +} } // namespace UnusedReturnValueCheck::UnusedReturnValueCheck(llvm::StringRef Name, @@ -157,16 +164,22 @@ void UnusedReturnValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { } void UnusedReturnValueCheck::registerMatchers(MatchFinder *Finder) { - auto MatchedDirectCallExpr = - expr(callExpr(callee(functionDecl( - // Don't match void overloads of checked functions. - unless(returns(voidType())), - anyOf(isInstantiatedFrom(matchers::matchesAnyListedName( - CheckedFunctions)), - returns(hasCanonicalType(hasDeclaration( - namedDecl(matchers::matchesAnyListedName( - CheckedReturnTypes))))))))) - .bind("match")); + auto MatchedDirectCallExpr = expr( + callExpr( + callee(functionDecl( + // Don't match void overloads of checked functions. + unless(returns(voidType())), + // Don't match copy or move assignment operator. + unless(cxxMethodDecl(isOperatorOverloading( + {OO_Equal, OO_PlusEqual, OO_MinusEqual, OO_StarEqual, + OO_SlashEqual, OO_PercentEqual, OO_CaretEqual, OO_AmpEqual, + OO_PipeEqual, OO_LessLessEqual, OO_GreaterGreaterEqual}))), + anyOf( + isInstantiatedFrom( + matchers::matchesAnyListedName(CheckedFunctions)), + returns(hasCanonicalType(hasDeclaration(namedDecl( + matchers::matchesAnyListedName(CheckedReturnTypes))))))))) + .bind("match")); auto CheckCastToVoid = AllowCastToVoid ? castExpr(unless(hasCastKind(CK_ToVoid))) : castExpr(); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index b5f025ce467a1..c7121fe07e0ad 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -152,9 +152,9 @@ Changes in existing checks - Improved :doc:`bugprone-unused-return-value ` check by updating the - parameter `CheckedFunctions` to support regexp and avoiding false postive for + parameter `CheckedFunctions` to support regexp, avoiding false positive for function with the same prefix as the default argument, e.g. ``std::unique_ptr`` - and ``std::unique``. + and ``std::unique``, avoiding false positive for assignment operator overloading. - Improved :doc:`bugprone-use-after-move ` check to also handle diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst index 9c01ef50b5381..9205ba98729c4 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst @@ -5,6 +5,8 @@ bugprone-unused-return-value Warns on unused function return values. The checked functions can be configured. +Operator overloading with assignment semantics are ignored. + Options ------- diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-avoid-assignment.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-avoid-assignment.cpp new file mode 100644 index 0000000000000..b4a41004adf89 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-return-value-avoid-assignment.cpp @@ -0,0 +1,30 @@ +// RUN: %check_clang_tidy %s bugprone-unused-return-value %t \ +// RUN: -config='{CheckOptions: \ +// RUN: {bugprone-unused-return-value.CheckedFunctions: "::*"}}' \ +// RUN: -- + +struct S { + S(){}; + S(S const &); + S(S &&); + S &operator=(S const &); + S &operator=(S &&); + S &operator+=(S); +}; + +S returnValue(); +S const &returnRef(); + +void bar() { + returnValue(); + // CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors + + S a{}; + a = returnValue(); + a.operator=(returnValue()); + + a = returnRef(); + a.operator=(returnRef()); + + a += returnRef(); +}