[clang-tidy] Don't warn about call to unresolved operator*

Summary:
The misc-unconventional-assign-operator check had a false positive
warning when the 'operator*' in 'return *this' was unresolved.

Change matcher to allow calls to unresolved operator.

Fixes PR31531.

Reviewers: alexfh, aaron.ballman

Subscribers: JDevlieghere, cfe-commits

Differential Revision: https://reviews.llvm.org/D29393

llvm-svn: 295176
This commit is contained in:
Malcolm Parsons 2017-02-15 14:01:41 +00:00
parent d717ce580b
commit 51642f9d0a
2 changed files with 26 additions and 1 deletions

View File

@ -58,7 +58,10 @@ void UnconventionalAssignOperatorCheck::registerMatchers(
this);
const auto IsBadReturnStatement = returnStmt(unless(has(ignoringParenImpCasts(
unaryOperator(hasOperatorName("*"), hasUnaryOperand(cxxThisExpr()))))));
anyOf(unaryOperator(hasOperatorName("*"), hasUnaryOperand(cxxThisExpr())),
cxxOperatorCallExpr(argumentCountIs(1),
callee(unresolvedLookupExpr()),
hasArgument(0, cxxThisExpr())))))));
const auto IsGoodAssign = cxxMethodDecl(IsAssign, HasGoodReturnType);
Finder->addMatcher(returnStmt(IsBadReturnStatement, forFunction(IsGoodAssign))

View File

@ -87,3 +87,25 @@ public:
return n;
}
};
namespace pr31531 {
enum E { e };
// This declaration makes the 'return *this' below have an unresolved operator
// in the class template, but not in an instantiation.
E operator*(E, E);
template <typename>
struct UnresolvedOperator {
UnresolvedOperator &operator=(const UnresolvedOperator &) { return *this; }
};
UnresolvedOperator<int> UnresolvedOperatorInt;
template <typename>
struct Template {
Template &operator=(const Template &) { return this; }
// CHECK-MESSAGES: :[[@LINE-1]]:43: warning: operator=() should always return '*this'
};
Template<int> TemplateInt;
}