Skip to content

Commit e435558

Browse files
authored
[clang-tidy] add 'IgnoreMarcos' option to 'special-member-functions' check (#143550)
1 parent 5ce5ed4 commit e435558

File tree

6 files changed

+109
-3
lines changed

6 files changed

+109
-3
lines changed

clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ using namespace clang::ast_matchers;
1818

1919
namespace clang::tidy::cppcoreguidelines {
2020

21+
namespace {
22+
AST_MATCHER(CXXRecordDecl, isInMacro) {
23+
return Node.getBeginLoc().isMacroID() && Node.getEndLoc().isMacroID();
24+
}
25+
} // namespace
26+
2127
SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck(
2228
StringRef Name, ClangTidyContext *Context)
2329
: ClangTidyCheck(Name, Context), AllowMissingMoveFunctions(Options.get(
@@ -26,7 +32,8 @@ SpecialMemberFunctionsCheck::SpecialMemberFunctionsCheck(
2632
AllowMissingMoveFunctionsWhenCopyIsDeleted(
2733
Options.get("AllowMissingMoveFunctionsWhenCopyIsDeleted", false)),
2834
AllowImplicitlyDeletedCopyOrMove(
29-
Options.get("AllowImplicitlyDeletedCopyOrMove", false)) {}
35+
Options.get("AllowImplicitlyDeletedCopyOrMove", false)),
36+
IgnoreMacros(Options.get("IgnoreMacros", true)) {}
3037

3138
void SpecialMemberFunctionsCheck::storeOptions(
3239
ClangTidyOptions::OptionMap &Opts) {
@@ -36,6 +43,7 @@ void SpecialMemberFunctionsCheck::storeOptions(
3643
AllowMissingMoveFunctionsWhenCopyIsDeleted);
3744
Options.store(Opts, "AllowImplicitlyDeletedCopyOrMove",
3845
AllowImplicitlyDeletedCopyOrMove);
46+
Options.store(Opts, "IgnoreMacros", IgnoreMacros);
3947
}
4048

4149
std::optional<TraversalKind>
@@ -45,11 +53,12 @@ SpecialMemberFunctionsCheck::getCheckTraversalKind() const {
4553
}
4654

4755
void SpecialMemberFunctionsCheck::registerMatchers(MatchFinder *Finder) {
48-
auto IsNotImplicitOrDeleted = anyOf(unless(isImplicit()), isDeleted());
56+
const auto IsNotImplicitOrDeleted = anyOf(unless(isImplicit()), isDeleted());
57+
const ast_matchers::internal::Matcher<CXXRecordDecl> Anything = anything();
4958

5059
Finder->addMatcher(
5160
cxxRecordDecl(
52-
unless(isImplicit()),
61+
unless(isImplicit()), IgnoreMacros ? unless(isInMacro()) : Anything,
5362
eachOf(has(cxxDestructorDecl(unless(isImplicit())).bind("dtor")),
5463
has(cxxConstructorDecl(isCopyConstructor(),
5564
IsNotImplicitOrDeleted)

clang-tools-extra/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class SpecialMemberFunctionsCheck : public ClangTidyCheck {
6969
const bool AllowMissingMoveFunctionsWhenCopyIsDeleted;
7070
const bool AllowImplicitlyDeletedCopyOrMove;
7171
ClassDefiningSpecialMembersMap ClassWithSpecialMembers;
72+
const bool IgnoreMacros;
7273
};
7374

7475
} // namespace clang::tidy::cppcoreguidelines

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ Changes in existing checks
201201
<clang-tidy/checks/cppcoreguidelines/avoid-goto>` check by adding the option
202202
`IgnoreMacros` to ignore ``goto`` labels defined in macros.
203203

204+
- Improved :doc:`cppcoreguidelines-special-member-functions
205+
<clang-tidy/checks/cppcoreguidelines/special-member-functions>` check by
206+
adding the option `IgnoreMacros` to ignore classes defined in macros.
207+
204208
- Improved :doc:`google-readability-namespace-comments
205209
<clang-tidy/checks/google/readability-namespace-comments>` check by adding
206210
the option `AllowOmittingNamespaceComments` to accept if a namespace comment
@@ -210,6 +214,10 @@ Changes in existing checks
210214
<clang-tidy/checks/hicpp/avoid-goto>` check by adding the option
211215
`IgnoreMacros` to ignore ``goto`` labels defined in macros.
212216

217+
- Improved :doc:`hicpp-special-member-functions
218+
<clang-tidy/checks/hicpp/special-member-functions>` check by adding the
219+
option `IgnoreMacros` to ignore classes defined in macros.
220+
213221
- Improved :doc:`llvm-namespace-comment
214222
<clang-tidy/checks/llvm/namespace-comment>` check by adding the option
215223
`AllowOmittingNamespaceComments` to accept if a namespace comment is omitted

clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/special-member-functions.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,8 @@ Options
8585
struct A : boost::noncopyable {
8686
~A() { std::cout << "dtor\n"; }
8787
};
88+
89+
.. option:: IgnoreMacros
90+
91+
If set to `true`, the check will not give warnings for classes defined
92+
inside macros. Default is `true`.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t -- -config="{CheckOptions: {cppcoreguidelines-special-member-functions.IgnoreMacros: false}}" --
2+
3+
class DefinesDestructor {
4+
~DefinesDestructor();
5+
};
6+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
7+
8+
class DefinesDefaultedDestructor {
9+
~DefinesDefaultedDestructor() = default;
10+
};
11+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDefaultedDestructor' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
12+
13+
class DefinesCopyConstructor {
14+
DefinesCopyConstructor(const DefinesCopyConstructor &);
15+
};
16+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
17+
18+
class DefinesNothing {
19+
};
20+
21+
class DefinesEverything {
22+
DefinesEverything(const DefinesEverything &);
23+
DefinesEverything &operator=(const DefinesEverything &);
24+
DefinesEverything(DefinesEverything &&);
25+
DefinesEverything &operator=(DefinesEverything &&);
26+
~DefinesEverything();
27+
};
28+
29+
#define DEFINE_DESTRUCTOR_ONLY(ClassName) \
30+
class ClassName { \
31+
~ClassName(); \
32+
};
33+
34+
#define DEFINE_COPY_CTOR_ONLY(ClassName) \
35+
class ClassName { \
36+
ClassName(const ClassName &); \
37+
};
38+
39+
#define DEFINE_CLASS_WITH_DTOR(ClassName) \
40+
class ClassName { \
41+
~ClassName(); \
42+
};
43+
44+
DEFINE_DESTRUCTOR_ONLY(MacroDefinedClass1)
45+
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: class 'MacroDefinedClass1' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
46+
DEFINE_COPY_CTOR_ONLY(MacroDefinedClass2)
47+
// CHECK-MESSAGES: [[@LINE-1]]:23: warning: class 'MacroDefinedClass2' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator
48+
DEFINE_CLASS_WITH_DTOR(MacroDefinedClass3)
49+
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: class 'MacroDefinedClass3' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
50+
51+
// Test partial macro expansion
52+
#define CLASS_NAME MacroNamedClass
53+
class CLASS_NAME {
54+
~MacroNamedClass();
55+
};
56+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'MacroNamedClass' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator
57+

clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/special-member-functions.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,29 @@ struct TemplateClass {
7070
// This should not cause problems.
7171
TemplateClass<int> InstantiationWithInt;
7272
TemplateClass<double> InstantiationWithDouble;
73+
74+
#define DEFINE_DESTRUCTOR_ONLY(ClassName) \
75+
class ClassName { \
76+
~ClassName(); \
77+
};
78+
79+
#define DEFINE_COPY_CTOR_ONLY(ClassName) \
80+
class ClassName { \
81+
ClassName(const ClassName &); \
82+
};
83+
84+
#define DEFINE_CLASS_WITH_DTOR(ClassName) \
85+
class ClassName { \
86+
~ClassName(); \
87+
};
88+
89+
DEFINE_DESTRUCTOR_ONLY(MacroDefinedClass1)
90+
DEFINE_COPY_CTOR_ONLY(MacroDefinedClass2)
91+
DEFINE_CLASS_WITH_DTOR(MacroDefinedClass3)
92+
93+
// Test partial macro expansion
94+
#define CLASS_NAME MacroNamedClass
95+
class CLASS_NAME {
96+
~MacroNamedClass();
97+
};
98+
// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'MacroNamedClass' defines a destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator

0 commit comments

Comments
 (0)