diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp --- a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp @@ -40,9 +40,12 @@ // Self-check: Code compares something with 'this' pointer. We don't check // whether it is actually the parameter what we compare. - const auto HasNoSelfCheck = cxxMethodDecl(unless( + const auto HasNoSelfCheck = cxxMethodDecl(unless(anyOf( hasDescendant(binaryOperator(hasAnyOperatorName("==", "!="), - has(ignoringParenCasts(cxxThisExpr())))))); + has(ignoringParenCasts(cxxThisExpr())))), + hasDescendant(cxxOperatorCallExpr( + hasAnyOverloadedOperatorName("==", "!="), argumentCountIs(2), + has(ignoringParenCasts(cxxThisExpr()))))))); // Both copy-and-swap and copy-and-move method creates a copy first and // assign it to 'this' with swap or move. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp @@ -212,6 +212,21 @@ T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo2; +template +bool operator!=(Foo2 &, Foo2 &) { + class Bar2 { + Bar2 &operator=(const Bar2 &other) { + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment] + p = other.p; + return *this; + } + + int *p; + }; +} + /////////////////////////////////////////////////////////////////// /// Test cases correctly ignored by the check. @@ -283,6 +298,21 @@ T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo; +template +bool operator!=(Foo &, Foo &) { + class Bar { + Bar &operator=(const Bar &other) { + if (this != &other) { + } + return *this; + } + + int *p; + }; +} + // There is no warning if the copy assignment operator gets the object by value. class PassedByValue { public: