summaryrefslogtreecommitdiffstats
path: root/lib/Analysis/ExprMutationAnalyzer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/ExprMutationAnalyzer.cpp')
-rw-r--r--lib/Analysis/ExprMutationAnalyzer.cpp53
1 files changed, 36 insertions, 17 deletions
diff --git a/lib/Analysis/ExprMutationAnalyzer.cpp b/lib/Analysis/ExprMutationAnalyzer.cpp
index 8414cb5c72..fb5a139e82 100644
--- a/lib/Analysis/ExprMutationAnalyzer.cpp
+++ b/lib/Analysis/ExprMutationAnalyzer.cpp
@@ -1,9 +1,8 @@
//===---------- ExprMutationAnalyzer.cpp ----------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
@@ -25,6 +24,18 @@ AST_MATCHER_P(CXXForRangeStmt, hasRangeStmt,
return InnerMatcher.matches(*Range, Finder, Builder);
}
+AST_MATCHER_P(Expr, maybeEvalCommaExpr,
+ ast_matchers::internal::Matcher<Expr>, InnerMatcher) {
+ const Expr* Result = &Node;
+ while (const auto *BOComma =
+ dyn_cast_or_null<BinaryOperator>(Result->IgnoreParens())) {
+ if (!BOComma->isCommaOp())
+ break;
+ Result = BOComma->getRHS();
+ }
+ return InnerMatcher.matches(*Result, Finder, Builder);
+}
+
const ast_matchers::internal::VariadicDynCastAllOfMatcher<Stmt, CXXTypeidExpr>
cxxTypeidExpr;
@@ -194,24 +205,28 @@ const Stmt *ExprMutationAnalyzer::findDeclPointeeMutation(
const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
// LHS of any assignment operators.
const auto AsAssignmentLhs =
- binaryOperator(isAssignmentOperator(), hasLHS(equalsNode(Exp)));
+ binaryOperator(isAssignmentOperator(),
+ hasLHS(maybeEvalCommaExpr(equalsNode(Exp))));
// Operand of increment/decrement operators.
const auto AsIncDecOperand =
unaryOperator(anyOf(hasOperatorName("++"), hasOperatorName("--")),
- hasUnaryOperand(equalsNode(Exp)));
+ hasUnaryOperand(maybeEvalCommaExpr(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))),
+ expr(anyOf(cxxMemberCallExpr(callee(NonConstMethod),
+ on(maybeEvalCommaExpr(equalsNode(Exp)))),
cxxOperatorCallExpr(callee(NonConstMethod),
- hasArgument(0, equalsNode(Exp))),
+ hasArgument(0,
+ maybeEvalCommaExpr(equalsNode(Exp)))),
callExpr(callee(expr(anyOf(
- unresolvedMemberExpr(hasObjectExpression(equalsNode(Exp))),
+ unresolvedMemberExpr(
+ hasObjectExpression(maybeEvalCommaExpr(equalsNode(Exp)))),
cxxDependentScopeMemberExpr(
- hasObjectExpression(equalsNode(Exp)))))))));
+ hasObjectExpression(maybeEvalCommaExpr(equalsNode(Exp))))))))));
// Taking address of 'Exp'.
// We're assuming 'Exp' is mutated as soon as its address is taken, though in
@@ -221,10 +236,11 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
unaryOperator(hasOperatorName("&"),
// A NoOp implicit cast is adding const.
unless(hasParent(implicitCastExpr(hasCastKind(CK_NoOp)))),
- hasUnaryOperand(equalsNode(Exp)));
+ hasUnaryOperand(maybeEvalCommaExpr(equalsNode(Exp))));
const auto AsPointerFromArrayDecay =
castExpr(hasCastKind(CK_ArrayToPointerDecay),
- unless(hasParent(arraySubscriptExpr())), has(equalsNode(Exp)));
+ unless(hasParent(arraySubscriptExpr())),
+ has(maybeEvalCommaExpr(equalsNode(Exp))));
// Treat calling `operator->()` of move-only classes as taking address.
// These are typically smart pointers with unique ownership so we treat
// mutation of pointee as mutation of the smart pointer itself.
@@ -232,7 +248,8 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
cxxOperatorCallExpr(hasOverloadedOperatorName("->"),
callee(cxxMethodDecl(ofClass(isMoveOnly()),
returns(nonConstPointerType()))),
- argumentCountIs(1), hasArgument(0, equalsNode(Exp)));
+ argumentCountIs(1),
+ hasArgument(0, maybeEvalCommaExpr(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.
@@ -240,7 +257,8 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
// findFunctionArgMutation which has additional smarts for handling forwarding
// references.
const auto NonConstRefParam = forEachArgumentWithParam(
- equalsNode(Exp), parmVarDecl(hasType(nonConstReferenceType())));
+ maybeEvalCommaExpr(equalsNode(Exp)),
+ parmVarDecl(hasType(nonConstReferenceType())));
const auto NotInstantiated = unless(hasDeclaration(isInstantiated()));
const auto AsNonConstRefArg = anyOf(
callExpr(NonConstRefParam, NotInstantiated),
@@ -248,8 +266,8 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
callExpr(callee(expr(anyOf(unresolvedLookupExpr(), unresolvedMemberExpr(),
cxxDependentScopeMemberExpr(),
hasType(templateTypeParmType())))),
- hasAnyArgument(equalsNode(Exp))),
- cxxUnresolvedConstructExpr(hasAnyArgument(equalsNode(Exp))));
+ hasAnyArgument(maybeEvalCommaExpr(equalsNode(Exp)))),
+ cxxUnresolvedConstructExpr(hasAnyArgument(maybeEvalCommaExpr(equalsNode(Exp)))));
// Captured by a lambda by reference.
// If we're initializing a capture with 'Exp' directly then we're initializing
@@ -262,7 +280,8 @@ const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) {
// For returning by value there will be an ImplicitCastExpr <LValueToRValue>.
// For returning by const-ref there will be an ImplicitCastExpr <NoOp> (for
// adding const.)
- const auto AsNonConstRefReturn = returnStmt(hasReturnValue(equalsNode(Exp)));
+ const auto AsNonConstRefReturn = returnStmt(hasReturnValue(
+ maybeEvalCommaExpr(equalsNode(Exp))));
const auto Matches =
match(findAll(stmt(anyOf(AsAssignmentLhs, AsIncDecOperand, AsNonConstThis,