diff --git a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp --- a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp @@ -60,7 +60,12 @@ anyOf(unaryOperator(hasOperatorName("*"), hasUnaryOperand(cxxThisExpr())), cxxOperatorCallExpr(argumentCountIs(1), callee(unresolvedLookupExpr()), - hasArgument(0, cxxThisExpr()))))))); + hasArgument(0, cxxThisExpr())), + cxxOperatorCallExpr( + hasOverloadedOperatorName("="), + hasArgument( + 0, unaryOperator(hasOperatorName("*"), + hasUnaryOperand(cxxThisExpr()))))))))); const auto IsGoodAssign = cxxMethodDecl(IsAssign, HasGoodReturnType); Finder->addMatcher(returnStmt(IsBadReturnStatement, forFunction(IsGoodAssign)) diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp @@ -109,3 +109,21 @@ Template TemplateInt; } + +struct AssignmentCallAtReturn { + AssignmentCallAtReturn &returnThis() { + return *this; + } + AssignmentCallAtReturn &operator=(int rhs) { + return *this; + } + AssignmentCallAtReturn &operator=(char rhs) { + // Allow call to assignment from other type. + return (*this = static_cast(rhs)); + } + AssignmentCallAtReturn &operator=(float rhs) { + // Do not allow calls to other functions. + return returnThis(); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator=() should always return '*this' + } +};