@@ -16,6 +16,18 @@ namespace clang {
16
16
namespace tidy {
17
17
namespace bugprone {
18
18
19
+ UnhandledSelfAssignmentCheck::UnhandledSelfAssignmentCheck (
20
+ StringRef Name, ClangTidyContext *Context)
21
+ : ClangTidyCheck(Name, Context),
22
+ WarnOnlyIfThisHasSuspiciousField (
23
+ Options.get(" WarnOnlyIfThisHasSuspiciousField" , true )) {}
24
+
25
+ void UnhandledSelfAssignmentCheck::storeOptions (
26
+ ClangTidyOptions::OptionMap &Opts) {
27
+ Options.store (Opts, " WarnOnlyIfThisHasSuspiciousField" ,
28
+ WarnOnlyIfThisHasSuspiciousField);
29
+ }
30
+
19
31
void UnhandledSelfAssignmentCheck::registerMatchers (MatchFinder *Finder) {
20
32
if (!getLangOpts ().CPlusPlus )
21
33
return ;
@@ -61,29 +73,32 @@ void UnhandledSelfAssignmentCheck::registerMatchers(MatchFinder *Finder) {
61
73
cxxMethodDecl (unless (hasDescendant (cxxMemberCallExpr (callee (cxxMethodDecl (
62
74
hasName (" operator=" ), ofClass (equalsBoundNode (" class" ))))))));
63
75
64
- // Matcher for standard smart pointers.
65
- const auto SmartPointerType = qualType (hasUnqualifiedDesugaredType (
66
- recordType (hasDeclaration (classTemplateSpecializationDecl (
67
- hasAnyName (" ::std::shared_ptr" , " ::std::unique_ptr" ,
68
- " ::std::weak_ptr" , " ::std::auto_ptr" ),
69
- templateArgumentCountIs (1 ))))));
70
-
71
- // We will warn only if the class has a pointer or a C array field which
72
- // probably causes a problem during self-assignment (e.g. first resetting the
73
- // pointer member, then trying to access the object pointed by the pointer, or
74
- // memcpy overlapping arrays).
75
- const auto ThisHasSuspiciousField = cxxMethodDecl (ofClass (cxxRecordDecl (
76
- has (fieldDecl (anyOf (hasType (pointerType ()), hasType (SmartPointerType),
77
- hasType (arrayType ())))))));
78
-
79
- Finder->addMatcher (
80
- cxxMethodDecl (ofClass (cxxRecordDecl ().bind (" class" )),
81
- isCopyAssignmentOperator (), IsUserDefined,
82
- HasReferenceParam, HasNoSelfCheck,
83
- unless (HasNonTemplateSelfCopy), unless (HasTemplateSelfCopy),
84
- HasNoNestedSelfAssign, ThisHasSuspiciousField)
85
- .bind (" copyAssignmentOperator" ),
86
- this );
76
+ DeclarationMatcher AdditionalMatcher = cxxMethodDecl ();
77
+ if (WarnOnlyIfThisHasSuspiciousField) {
78
+ // Matcher for standard smart pointers.
79
+ const auto SmartPointerType = qualType (hasUnqualifiedDesugaredType (
80
+ recordType (hasDeclaration (classTemplateSpecializationDecl (
81
+ hasAnyName (" ::std::shared_ptr" , " ::std::unique_ptr" ,
82
+ " ::std::weak_ptr" , " ::std::auto_ptr" ),
83
+ templateArgumentCountIs (1 ))))));
84
+
85
+ // We will warn only if the class has a pointer or a C array field which
86
+ // probably causes a problem during self-assignment (e.g. first resetting
87
+ // the pointer member, then trying to access the object pointed by the
88
+ // pointer, or memcpy overlapping arrays).
89
+ AdditionalMatcher = cxxMethodDecl (ofClass (cxxRecordDecl (
90
+ has (fieldDecl (anyOf (hasType (pointerType ()), hasType (SmartPointerType),
91
+ hasType (arrayType ())))))));
92
+ }
93
+
94
+ Finder->addMatcher (cxxMethodDecl (ofClass (cxxRecordDecl ().bind (" class" )),
95
+ isCopyAssignmentOperator (), IsUserDefined,
96
+ HasReferenceParam, HasNoSelfCheck,
97
+ unless (HasNonTemplateSelfCopy),
98
+ unless (HasTemplateSelfCopy),
99
+ HasNoNestedSelfAssign, AdditionalMatcher)
100
+ .bind (" copyAssignmentOperator" ),
101
+ this );
87
102
}
88
103
89
104
void UnhandledSelfAssignmentCheck::check (
0 commit comments