Skip to content

Commit 208fa9a

Browse files
committed
[clang-tidy] Ignore used special-members in modernize-use-equals-delete
Special members marked as used, or with out-of-line definition should not raise an warning now. Fixes: llvm#33759 Reviewed By: carlosgalvezp Differential Revision: https://reviews.llvm.org/D158486
1 parent 7203497 commit 208fa9a

File tree

4 files changed

+74
-20
lines changed

4 files changed

+74
-20
lines changed

clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.cpp

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,53 @@ using namespace clang::ast_matchers;
1515

1616
namespace clang::tidy::modernize {
1717

18+
namespace {
19+
AST_MATCHER(FunctionDecl, hasAnyDefinition) {
20+
if (Node.hasBody() || Node.isPure() || Node.isDefaulted() || Node.isDeleted())
21+
return true;
22+
23+
if (const FunctionDecl *Definition = Node.getDefinition())
24+
if (Definition->hasBody() || Definition->isPure() ||
25+
Definition->isDefaulted() || Definition->isDeleted())
26+
return true;
27+
28+
return false;
29+
}
30+
31+
AST_MATCHER(Decl, isUsed) { return Node.isUsed(); }
32+
33+
AST_MATCHER(CXXMethodDecl, isSpecialFunction) {
34+
if (const auto *Constructor = dyn_cast<CXXConstructorDecl>(&Node))
35+
return Constructor->isDefaultConstructor() ||
36+
Constructor->isCopyOrMoveConstructor();
37+
38+
return isa<CXXDestructorDecl>(Node) || Node.isCopyAssignmentOperator() ||
39+
Node.isMoveAssignmentOperator();
40+
}
41+
} // namespace
42+
1843
static const char SpecialFunction[] = "SpecialFunction";
1944
static const char DeletedNotPublic[] = "DeletedNotPublic";
2045

46+
UseEqualsDeleteCheck::UseEqualsDeleteCheck(StringRef Name,
47+
ClangTidyContext *Context)
48+
: ClangTidyCheck(Name, Context),
49+
IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {}
50+
2151
void UseEqualsDeleteCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
2252
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
2353
}
2454

2555
void UseEqualsDeleteCheck::registerMatchers(MatchFinder *Finder) {
26-
auto PrivateSpecialFn = cxxMethodDecl(
27-
isPrivate(),
28-
anyOf(cxxConstructorDecl(anyOf(isDefaultConstructor(),
29-
isCopyConstructor(), isMoveConstructor())),
30-
cxxMethodDecl(
31-
anyOf(isCopyAssignmentOperator(), isMoveAssignmentOperator())),
32-
cxxDestructorDecl()));
56+
auto PrivateSpecialFn = cxxMethodDecl(isPrivate(), isSpecialFunction());
3357

3458
Finder->addMatcher(
3559
cxxMethodDecl(
36-
PrivateSpecialFn,
37-
unless(anyOf(hasAnyBody(stmt()), isDefaulted(), isDeleted(),
38-
ast_matchers::isTemplateInstantiation(),
39-
// Ensure that all methods except private special member
40-
// functions are defined.
41-
hasParent(cxxRecordDecl(hasMethod(unless(
42-
anyOf(PrivateSpecialFn, hasAnyBody(stmt()), isPure(),
43-
isDefaulted(), isDeleted()))))))))
60+
PrivateSpecialFn, unless(hasAnyDefinition()), unless(isUsed()),
61+
// Ensure that all methods except private special member functions are
62+
// defined.
63+
unless(ofClass(hasMethod(cxxMethodDecl(unless(PrivateSpecialFn),
64+
unless(hasAnyDefinition()))))))
4465
.bind(SpecialFunction),
4566
this);
4667

@@ -55,7 +76,7 @@ void UseEqualsDeleteCheck::check(const MatchFinder::MatchResult &Result) {
5576
SourceLocation EndLoc = Lexer::getLocForEndOfToken(
5677
Func->getEndLoc(), 0, *Result.SourceManager, getLangOpts());
5778

58-
if (Func->getLocation().isMacroID() && IgnoreMacros)
79+
if (IgnoreMacros && Func->getLocation().isMacroID())
5980
return;
6081
// FIXME: Improve FixItHint to make the method public.
6182
diag(Func->getLocation(),
@@ -66,7 +87,7 @@ void UseEqualsDeleteCheck::check(const MatchFinder::MatchResult &Result) {
6687
// Ignore this warning in macros, since it's extremely noisy in code using
6788
// DISALLOW_COPY_AND_ASSIGN-style macros and there's no easy way to
6889
// automatically fix the warning when macros are in play.
69-
if (Func->getLocation().isMacroID() && IgnoreMacros)
90+
if (IgnoreMacros && Func->getLocation().isMacroID())
7091
return;
7192
// FIXME: Add FixItHint to make the method public.
7293
diag(Func->getLocation(), "deleted member function should be public");

clang-tools-extra/clang-tidy/modernize/UseEqualsDeleteCheck.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,16 @@ namespace clang::tidy::modernize {
3434
/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-equals-delete.html
3535
class UseEqualsDeleteCheck : public ClangTidyCheck {
3636
public:
37-
UseEqualsDeleteCheck(StringRef Name, ClangTidyContext *Context)
38-
: ClangTidyCheck(Name, Context),
39-
IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {}
37+
UseEqualsDeleteCheck(StringRef Name, ClangTidyContext *Context);
4038
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
4139
return LangOpts.CPlusPlus;
4240
}
4341
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
4442
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
4543
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
44+
std::optional<TraversalKind> getCheckTraversalKind() const override {
45+
return TK_IgnoreUnlessSpelledInSource;
46+
}
4647

4748
private:
4849
const bool IgnoreMacros;

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,10 @@ Changes in existing checks
234234
<clang-tidy/checks/modernize/loop-convert>` to support for-loops with
235235
iterators initialized by free functions like ``begin``, ``end``, or ``size``.
236236

237+
- Improved :doc:`modernize-use-equals-delete
238+
<clang-tidy/checks/modernize/use-equals-delete>` check to ignore
239+
false-positives when special member function is actually used or implicit.
240+
237241
- Improved :doc:`modernize-use-std-print
238242
<clang-tidy/checks/modernize/use-std-print>` check to accurately generate
239243
fixes for reordering arguments.

clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-delete.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,3 +191,31 @@ class C {
191191
private:
192192
MACRO(C);
193193
};
194+
195+
namespace PR33759 {
196+
197+
class Number {
198+
private:
199+
Number();
200+
~Number();
201+
202+
public:
203+
static Number& getNumber() {
204+
static Number number;
205+
return number;
206+
}
207+
208+
int getIntValue() { return (int)someFloat; }
209+
float getFloatValue() { return someFloat; }
210+
private:
211+
float someFloat;
212+
};
213+
214+
class Number2 {
215+
private:
216+
Number2();
217+
~Number2();
218+
public:
219+
static Number& getNumber();
220+
};
221+
}

0 commit comments

Comments
 (0)