diff options
author | Shuai Wang <shuaiwang@google.com> | 2018-09-10 18:05:13 +0000 |
---|---|---|
committer | Shuai Wang <shuaiwang@google.com> | 2018-09-10 18:05:13 +0000 |
commit | d204c088c7d8f6892bb0145794dd243f8c91ea96 (patch) | |
tree | 4abfc40bc5502f38654346184366b71b9f21f056 /clang-tidy/utils | |
parent | 91c7d8355f0e8a1f5a387f5d00f0775ead0b3fae (diff) |
[clang-tidy] Handle unresolved expressions in ExprMutationAnalyzer
Summary:
- If a function is unresolved, assume it mutates its arguments
- Follow unresolved member expressions for nested mutations
Reviewers: aaron.ballman, JonasToth, george.karpenkov
Subscribers: xazax.hun, a.sidorin, cfe-commits
Differential Revision: https://reviews.llvm.org/D50619
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@341848 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-tidy/utils')
-rw-r--r-- | clang-tidy/utils/ExprMutationAnalyzer.cpp | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/clang-tidy/utils/ExprMutationAnalyzer.cpp b/clang-tidy/utils/ExprMutationAnalyzer.cpp index 424fa8f6..f1cd1daf 100644 --- a/clang-tidy/utils/ExprMutationAnalyzer.cpp +++ b/clang-tidy/utils/ExprMutationAnalyzer.cpp @@ -145,11 +145,16 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) { hasUnaryOperand(equalsNode(Exp))); // Invoking non-const member function. + // A member function is assumed to be non-const when it is unresolved. const auto NonConstMethod = cxxMethodDecl(unless(isConst())); const auto AsNonConstThis = expr(anyOf(cxxMemberCallExpr(callee(NonConstMethod), on(equalsNode(Exp))), cxxOperatorCallExpr(callee(NonConstMethod), - hasArgument(0, equalsNode(Exp))))); + hasArgument(0, equalsNode(Exp))), + callExpr(callee(expr(anyOf( + unresolvedMemberExpr(hasObjectExpression(equalsNode(Exp))), + cxxDependentScopeMemberExpr( + hasObjectExpression(equalsNode(Exp))))))))); // Taking address of 'Exp'. // We're assuming 'Exp' is mutated as soon as its address is taken, though in @@ -165,10 +170,16 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) { unless(hasParent(arraySubscriptExpr())), has(equalsNode(Exp))); // Used as non-const-ref argument when calling a function. + // An argument is assumed to be non-const-ref when the function is unresolved. const auto NonConstRefParam = forEachArgumentWithParam( equalsNode(Exp), parmVarDecl(hasType(nonConstReferenceType()))); - const auto AsNonConstRefArg = - anyOf(callExpr(NonConstRefParam), cxxConstructExpr(NonConstRefParam)); + const auto AsNonConstRefArg = anyOf( + callExpr(NonConstRefParam), cxxConstructExpr(NonConstRefParam), + callExpr(callee(expr(anyOf(unresolvedLookupExpr(), unresolvedMemberExpr(), + cxxDependentScopeMemberExpr(), + hasType(templateTypeParmType())))), + hasAnyArgument(equalsNode(Exp))), + cxxUnresolvedConstructExpr(hasAnyArgument(equalsNode(Exp)))); // Captured by a lambda by reference. // If we're initializing a capture with 'Exp' directly then we're initializing @@ -195,9 +206,12 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) { const Stmt *ExprMutationAnalyzer::findMemberMutation(const Expr *Exp) { // Check whether any member of 'Exp' is mutated. - const auto MemberExprs = match( - findAll(memberExpr(hasObjectExpression(equalsNode(Exp))).bind("expr")), - *Stm, *Context); + const auto MemberExprs = + match(findAll(expr(anyOf(memberExpr(hasObjectExpression(equalsNode(Exp))), + cxxDependentScopeMemberExpr( + hasObjectExpression(equalsNode(Exp))))) + .bind("expr")), + *Stm, *Context); return findExprMutation(MemberExprs); } |