[clang-tidy]: Add cert-oop54-cpp alias for bugprone-unhandled-self-assignment
Summary:
Added WarnOnlyIfThisHasSuspiciousField option to allow
to catch any copy assignment operator independently from
the container class's fields.
Added the cert alias using this option.
Reviewers: aaron.ballman
Reviewed By: aaron.ballman
Subscribers: mgorny, Eugene.Zelenko, xazax.hun, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D62192
llvm-svn: 361550
diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp
index b529f72..14f5e15 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp
@@ -16,6 +16,18 @@
namespace tidy {
namespace bugprone {
+UnhandledSelfAssignmentCheck::UnhandledSelfAssignmentCheck(
+ StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ WarnOnlyIfThisHasSuspiciousField(
+ Options.get("WarnOnlyIfThisHasSuspiciousField", true)) {}
+
+void UnhandledSelfAssignmentCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "WarnOnlyIfThisHasSuspiciousField",
+ WarnOnlyIfThisHasSuspiciousField);
+}
+
void UnhandledSelfAssignmentCheck::registerMatchers(MatchFinder *Finder) {
if (!getLangOpts().CPlusPlus)
return;
@@ -61,29 +73,32 @@
cxxMethodDecl(unless(hasDescendant(cxxMemberCallExpr(callee(cxxMethodDecl(
hasName("operator="), ofClass(equalsBoundNode("class"))))))));
- // Matcher for standard smart pointers.
- const auto SmartPointerType = qualType(hasUnqualifiedDesugaredType(
- recordType(hasDeclaration(classTemplateSpecializationDecl(
- hasAnyName("::std::shared_ptr", "::std::unique_ptr",
- "::std::weak_ptr", "::std::auto_ptr"),
- templateArgumentCountIs(1))))));
+ DeclarationMatcher AdditionalMatcher = cxxMethodDecl();
+ if (WarnOnlyIfThisHasSuspiciousField) {
+ // Matcher for standard smart pointers.
+ const auto SmartPointerType = qualType(hasUnqualifiedDesugaredType(
+ recordType(hasDeclaration(classTemplateSpecializationDecl(
+ hasAnyName("::std::shared_ptr", "::std::unique_ptr",
+ "::std::weak_ptr", "::std::auto_ptr"),
+ templateArgumentCountIs(1))))));
- // We will warn only if the class has a pointer or a C array field which
- // probably causes a problem during self-assignment (e.g. first resetting the
- // pointer member, then trying to access the object pointed by the pointer, or
- // memcpy overlapping arrays).
- const auto ThisHasSuspiciousField = cxxMethodDecl(ofClass(cxxRecordDecl(
- has(fieldDecl(anyOf(hasType(pointerType()), hasType(SmartPointerType),
- hasType(arrayType())))))));
+ // We will warn only if the class has a pointer or a C array field which
+ // probably causes a problem during self-assignment (e.g. first resetting
+ // the pointer member, then trying to access the object pointed by the
+ // pointer, or memcpy overlapping arrays).
+ AdditionalMatcher = cxxMethodDecl(ofClass(cxxRecordDecl(
+ has(fieldDecl(anyOf(hasType(pointerType()), hasType(SmartPointerType),
+ hasType(arrayType())))))));
+ }
- Finder->addMatcher(
- cxxMethodDecl(ofClass(cxxRecordDecl().bind("class")),
- isCopyAssignmentOperator(), IsUserDefined,
- HasReferenceParam, HasNoSelfCheck,
- unless(HasNonTemplateSelfCopy), unless(HasTemplateSelfCopy),
- HasNoNestedSelfAssign, ThisHasSuspiciousField)
- .bind("copyAssignmentOperator"),
- this);
+ Finder->addMatcher(cxxMethodDecl(ofClass(cxxRecordDecl().bind("class")),
+ isCopyAssignmentOperator(), IsUserDefined,
+ HasReferenceParam, HasNoSelfCheck,
+ unless(HasNonTemplateSelfCopy),
+ unless(HasTemplateSelfCopy),
+ HasNoNestedSelfAssign, AdditionalMatcher)
+ .bind("copyAssignmentOperator"),
+ this);
}
void UnhandledSelfAssignmentCheck::check(