Skip to content

Commit 4fdf10f

Browse files
authored
[clang-tidy]avoid bugprone-unused-return-value false positive for assignment operator overloading (#84489)
1 parent e733d7e commit 4fdf10f

File tree

4 files changed

+57
-12
lines changed

4 files changed

+57
-12
lines changed

clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include "../utils/OptionsUtils.h"
1212
#include "clang/AST/ASTContext.h"
1313
#include "clang/ASTMatchers/ASTMatchFinder.h"
14+
#include "clang/ASTMatchers/ASTMatchers.h"
15+
#include "clang/Basic/OperatorKinds.h"
1416

1517
using namespace clang::ast_matchers;
1618
using namespace clang::ast_matchers::internal;
@@ -28,6 +30,11 @@ AST_MATCHER_P(FunctionDecl, isInstantiatedFrom, Matcher<FunctionDecl>,
2830
return InnerMatcher.matches(InstantiatedFrom ? *InstantiatedFrom : Node,
2931
Finder, Builder);
3032
}
33+
34+
AST_MATCHER_P(CXXMethodDecl, isOperatorOverloading,
35+
llvm::SmallVector<OverloadedOperatorKind>, Kinds) {
36+
return llvm::is_contained(Kinds, Node.getOverloadedOperator());
37+
}
3138
} // namespace
3239

3340
UnusedReturnValueCheck::UnusedReturnValueCheck(llvm::StringRef Name,
@@ -157,16 +164,22 @@ void UnusedReturnValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
157164
}
158165

159166
void UnusedReturnValueCheck::registerMatchers(MatchFinder *Finder) {
160-
auto MatchedDirectCallExpr =
161-
expr(callExpr(callee(functionDecl(
162-
// Don't match void overloads of checked functions.
163-
unless(returns(voidType())),
164-
anyOf(isInstantiatedFrom(matchers::matchesAnyListedName(
165-
CheckedFunctions)),
166-
returns(hasCanonicalType(hasDeclaration(
167-
namedDecl(matchers::matchesAnyListedName(
168-
CheckedReturnTypes)))))))))
169-
.bind("match"));
167+
auto MatchedDirectCallExpr = expr(
168+
callExpr(
169+
callee(functionDecl(
170+
// Don't match void overloads of checked functions.
171+
unless(returns(voidType())),
172+
// Don't match copy or move assignment operator.
173+
unless(cxxMethodDecl(isOperatorOverloading(
174+
{OO_Equal, OO_PlusEqual, OO_MinusEqual, OO_StarEqual,
175+
OO_SlashEqual, OO_PercentEqual, OO_CaretEqual, OO_AmpEqual,
176+
OO_PipeEqual, OO_LessLessEqual, OO_GreaterGreaterEqual}))),
177+
anyOf(
178+
isInstantiatedFrom(
179+
matchers::matchesAnyListedName(CheckedFunctions)),
180+
returns(hasCanonicalType(hasDeclaration(namedDecl(
181+
matchers::matchesAnyListedName(CheckedReturnTypes)))))))))
182+
.bind("match"));
170183

171184
auto CheckCastToVoid =
172185
AllowCastToVoid ? castExpr(unless(hasCastKind(CK_ToVoid))) : castExpr();

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ Changes in existing checks
152152

153153
- Improved :doc:`bugprone-unused-return-value
154154
<clang-tidy/checks/bugprone/unused-return-value>` check by updating the
155-
parameter `CheckedFunctions` to support regexp and avoiding false postive for
155+
parameter `CheckedFunctions` to support regexp, avoiding false positive for
156156
function with the same prefix as the default argument, e.g. ``std::unique_ptr``
157-
and ``std::unique``.
157+
and ``std::unique``, avoiding false positive for assignment operator overloading.
158158

159159
- Improved :doc:`bugprone-use-after-move
160160
<clang-tidy/checks/bugprone/use-after-move>` check to also handle

clang-tools-extra/docs/clang-tidy/checks/bugprone/unused-return-value.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ bugprone-unused-return-value
55

66
Warns on unused function return values. The checked functions can be configured.
77

8+
Operator overloading with assignment semantics are ignored.
9+
810
Options
911
-------
1012

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %check_clang_tidy %s bugprone-unused-return-value %t \
2+
// RUN: -config='{CheckOptions: \
3+
// RUN: {bugprone-unused-return-value.CheckedFunctions: "::*"}}' \
4+
// RUN: --
5+
6+
struct S {
7+
S(){};
8+
S(S const &);
9+
S(S &&);
10+
S &operator=(S const &);
11+
S &operator=(S &&);
12+
S &operator+=(S);
13+
};
14+
15+
S returnValue();
16+
S const &returnRef();
17+
18+
void bar() {
19+
returnValue();
20+
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors
21+
22+
S a{};
23+
a = returnValue();
24+
a.operator=(returnValue());
25+
26+
a = returnRef();
27+
a.operator=(returnRef());
28+
29+
a += returnRef();
30+
}

0 commit comments

Comments
 (0)