Skip to content

Commit 950b6dc

Browse files
authored
Checking that some kind of constructor is called and followed by a swap
1 parent 79d5db4 commit 950b6dc

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,23 @@ void UnhandledSelfAssignmentCheck::registerMatchers(MatchFinder *Finder) {
6868
const auto HasNoNestedSelfAssign =
6969
cxxMethodDecl(unless(hasDescendant(cxxMemberCallExpr(callee(cxxMethodDecl(
7070
hasName("operator="), ofClass(equalsBoundNode("class"))))))));
71-
71+
72+
// Checking that some kind of constructor is called and followed by a `swap`:
73+
// T& operator=(const T& other) {
74+
// T tmp{this->internal_data(), some, other, args};
75+
// swap(tmp);
76+
// return *this;
77+
// }
78+
const auto HasCopyAndSwap = cxxMethodDecl(
79+
ofClass(cxxRecordDecl(unless(hasAncestor(classTemplateDecl())))),
80+
hasDescendant(
81+
stmt(hasDescendant(
82+
varDecl(hasType(cxxRecordDecl(equalsBoundNode("class"))))
83+
.bind("tmp_var")),
84+
hasDescendant(callExpr(callee(functionDecl(hasName("swap"))),
85+
hasAnyArgument(declRefExpr(to(varDecl(
86+
equalsBoundNode("tmp_var"))))))))));
87+
7288
DeclarationMatcher AdditionalMatcher = cxxMethodDecl();
7389
if (WarnOnlyIfThisHasSuspiciousField) {
7490
// Matcher for standard smart pointers.
@@ -94,6 +110,7 @@ void UnhandledSelfAssignmentCheck::registerMatchers(MatchFinder *Finder) {
94110
HasReferenceParam, HasNoSelfCheck,
95111
unless(HasNonTemplateSelfCopy),
96112
unless(HasTemplateSelfCopy),
113+
unless(HasCopyAndSwap),
97114
HasNoNestedSelfAssign, AdditionalMatcher)
98115
.bind("copyAssignmentOperator"),
99116
this);

0 commit comments

Comments
 (0)