From aaaa310de21650e1234f6ef991b676616c2a36da Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Sun, 16 Sep 2018 21:09:50 +0000 Subject: [PATCH] [NFC] Minor refactoring to setup the stage for supporting pointers in ExprMutationAnalyzer llvm-svn: 342353 --- .../clang/Analysis/Analyses/ExprMutationAnalyzer.h | 20 ++++ clang/lib/Analysis/ExprMutationAnalyzer.cpp | 129 ++++++++++++++------- 2 files changed, 106 insertions(+), 43 deletions(-) diff --git a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h index f75157d..edc6e00 100644 --- a/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h +++ b/clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h @@ -31,13 +31,32 @@ public: const Stmt *findMutation(const Expr *Exp); const Stmt *findMutation(const Decl *Dec); + bool isPointeeMutated(const Expr *Exp) { + return findPointeeMutation(Exp) != nullptr; + } + bool isPointeeMutated(const Decl *Dec) { + return findPointeeMutation(Dec) != nullptr; + } + const Stmt *findPointeeMutation(const Expr *Exp); + const Stmt *findPointeeMutation(const Decl *Dec); + private: + using MutationFinder = const Stmt *(ExprMutationAnalyzer::*)(const Expr *); using ResultMap = llvm::DenseMap; + const Stmt *findMutationMemoized(const Expr *Exp, + llvm::ArrayRef Finders, + ResultMap &MemoizedResults); + const Stmt *tryEachDeclRef(const Decl *Dec, MutationFinder Finder); + bool isUnevaluated(const Expr *Exp); const Stmt *findExprMutation(ArrayRef Matches); const Stmt *findDeclMutation(ArrayRef Matches); + const Stmt * + findExprPointeeMutation(ArrayRef Matches); + const Stmt * + findDeclPointeeMutation(ArrayRef Matches); const Stmt *findDirectMutation(const Expr *Exp); const Stmt *findMemberMutation(const Expr *Exp); @@ -53,6 +72,7 @@ private: std::unique_ptr> FuncParmAnalyzer; ResultMap Results; + ResultMap PointeeResults; }; // A convenient wrapper around ExprMutationAnalyzer for analyzing function diff --git a/clang/lib/Analysis/ExprMutationAnalyzer.cpp b/clang/lib/Analysis/ExprMutationAnalyzer.cpp index f8ede47..50d4d0b 100644 --- a/clang/lib/Analysis/ExprMutationAnalyzer.cpp +++ b/clang/lib/Analysis/ExprMutationAnalyzer.cpp @@ -64,33 +64,83 @@ const auto isMoveOnly = [] { unless(isDeleted())))))); }; +template struct NodeID; +template <> struct NodeID { static const std::string value; }; +template <> struct NodeID { static const std::string value; }; +const std::string NodeID::value = "expr"; +const std::string NodeID::value = "decl"; + +template +const Stmt *tryEachMatch(ArrayRef Matches, + ExprMutationAnalyzer *Analyzer, F Finder) { + const StringRef ID = NodeID::value; + for (const auto &Nodes : Matches) { + if (const Stmt *S = (Analyzer->*Finder)(Nodes.getNodeAs(ID))) + return S; + } + return nullptr; +} + } // namespace const Stmt *ExprMutationAnalyzer::findMutation(const Expr *Exp) { - const auto Memoized = Results.find(Exp); - if (Memoized != Results.end()) + return findMutationMemoized(Exp, + {&ExprMutationAnalyzer::findDirectMutation, + &ExprMutationAnalyzer::findMemberMutation, + &ExprMutationAnalyzer::findArrayElementMutation, + &ExprMutationAnalyzer::findCastMutation, + &ExprMutationAnalyzer::findRangeLoopMutation, + &ExprMutationAnalyzer::findReferenceMutation, + &ExprMutationAnalyzer::findFunctionArgMutation}, + Results); +} + +const Stmt *ExprMutationAnalyzer::findMutation(const Decl *Dec) { + return tryEachDeclRef(Dec, &ExprMutationAnalyzer::findMutation); +} + +const Stmt *ExprMutationAnalyzer::findPointeeMutation(const Expr *Exp) { + return findMutationMemoized(Exp, {/*TODO*/}, PointeeResults); +} + +const Stmt *ExprMutationAnalyzer::findPointeeMutation(const Decl *Dec) { + return tryEachDeclRef(Dec, &ExprMutationAnalyzer::findPointeeMutation); +} + +const Stmt *ExprMutationAnalyzer::findMutationMemoized( + const Expr *Exp, llvm::ArrayRef Finders, + ResultMap &MemoizedResults) { + const auto Memoized = MemoizedResults.find(Exp); + if (Memoized != MemoizedResults.end()) return Memoized->second; if (isUnevaluated(Exp)) - return Results[Exp] = nullptr; - - for (const auto &Finder : {&ExprMutationAnalyzer::findDirectMutation, - &ExprMutationAnalyzer::findMemberMutation, - &ExprMutationAnalyzer::findArrayElementMutation, - &ExprMutationAnalyzer::findCastMutation, - &ExprMutationAnalyzer::findRangeLoopMutation, - &ExprMutationAnalyzer::findReferenceMutation, - &ExprMutationAnalyzer::findFunctionArgMutation}) { + return MemoizedResults[Exp] = nullptr; + + for (const auto &Finder : Finders) { if (const Stmt *S = (this->*Finder)(Exp)) - return Results[Exp] = S; + return MemoizedResults[Exp] = S; } - return Results[Exp] = nullptr; + return MemoizedResults[Exp] = nullptr; +} + +const Stmt *ExprMutationAnalyzer::tryEachDeclRef(const Decl *Dec, + MutationFinder Finder) { + const auto Refs = + match(findAll(declRefExpr(to(equalsNode(Dec))).bind(NodeID::value)), + Stm, Context); + for (const auto &RefNodes : Refs) { + const auto *E = RefNodes.getNodeAs(NodeID::value); + if ((this->*Finder)(E)) + return E; + } + return nullptr; } bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) { return selectFirst( - "expr", + NodeID::value, match( findAll( expr(equalsNode(Exp), @@ -115,37 +165,30 @@ bool ExprMutationAnalyzer::isUnevaluated(const Expr *Exp) { genericSelectionExpr(hasControllingExpr( hasDescendant(equalsNode(Exp)))), cxxNoexceptExpr()))))) - .bind("expr")), + .bind(NodeID::value)), Stm, Context)) != nullptr; } const Stmt * ExprMutationAnalyzer::findExprMutation(ArrayRef Matches) { - for (const auto &Nodes : Matches) { - if (const Stmt *S = findMutation(Nodes.getNodeAs("expr"))) - return S; - } - return nullptr; + return tryEachMatch(Matches, this, &ExprMutationAnalyzer::findMutation); } const Stmt * ExprMutationAnalyzer::findDeclMutation(ArrayRef Matches) { - for (const auto &DeclNodes : Matches) { - if (const Stmt *S = findMutation(DeclNodes.getNodeAs("decl"))) - return S; - } - return nullptr; + return tryEachMatch(Matches, this, &ExprMutationAnalyzer::findMutation); } -const Stmt *ExprMutationAnalyzer::findMutation(const Decl *Dec) { - const auto Refs = match( - findAll(declRefExpr(to(equalsNode(Dec))).bind("expr")), Stm, Context); - for (const auto &RefNodes : Refs) { - const auto *E = RefNodes.getNodeAs("expr"); - if (findMutation(E)) - return E; - } - return nullptr; +const Stmt *ExprMutationAnalyzer::findExprPointeeMutation( + ArrayRef Matches) { + return tryEachMatch(Matches, this, + &ExprMutationAnalyzer::findPointeeMutation); +} + +const Stmt *ExprMutationAnalyzer::findDeclPointeeMutation( + ArrayRef Matches) { + return tryEachMatch(Matches, this, + &ExprMutationAnalyzer::findPointeeMutation); } const Stmt *ExprMutationAnalyzer::findDirectMutation(const Expr *Exp) { @@ -237,7 +280,7 @@ const Stmt *ExprMutationAnalyzer::findMemberMutation(const Expr *Exp) { match(findAll(expr(anyOf(memberExpr(hasObjectExpression(equalsNode(Exp))), cxxDependentScopeMemberExpr( hasObjectExpression(equalsNode(Exp))))) - .bind("expr")), + .bind(NodeID::value)), Stm, Context); return findExprMutation(MemberExprs); } @@ -246,7 +289,7 @@ const Stmt *ExprMutationAnalyzer::findArrayElementMutation(const Expr *Exp) { // Check whether any element of an array is mutated. const auto SubscriptExprs = match( findAll(arraySubscriptExpr(hasBase(ignoringImpCasts(equalsNode(Exp)))) - .bind("expr")), + .bind(NodeID::value)), Stm, Context); return findExprMutation(SubscriptExprs); } @@ -259,7 +302,7 @@ const Stmt *ExprMutationAnalyzer::findCastMutation(const Expr *Exp) { nonConstReferenceType())), implicitCastExpr(hasImplicitDestinationType( nonConstReferenceType())))) - .bind("expr")), + .bind(NodeID::value)), Stm, Context); return findExprMutation(Casts); } @@ -269,8 +312,8 @@ const Stmt *ExprMutationAnalyzer::findRangeLoopMutation(const Expr *Exp) { // check all declRefExpr of the loop variable. const auto LoopVars = match(findAll(cxxForRangeStmt( - hasLoopVariable( - varDecl(hasType(nonConstReferenceType())).bind("decl")), + hasLoopVariable(varDecl(hasType(nonConstReferenceType())) + .bind(NodeID::value)), hasRangeInit(equalsNode(Exp)))), Stm, Context); return findDeclMutation(LoopVars); @@ -286,7 +329,7 @@ const Stmt *ExprMutationAnalyzer::findReferenceMutation(const Expr *Exp) { callee(cxxMethodDecl(ofClass(isMoveOnly()), returns(nonConstReferenceType()))), argumentCountIs(1), hasArgument(0, equalsNode(Exp))) - .bind("expr")), + .bind(NodeID::value)), Stm, Context); if (const Stmt *S = findExprMutation(Ref)) return S; @@ -305,7 +348,7 @@ const Stmt *ExprMutationAnalyzer::findReferenceMutation(const Expr *Exp) { // that separately. unless(hasParent(declStmt(hasParent( cxxForRangeStmt(hasRangeStmt(equalsBoundNode("stmt")))))))) - .bind("decl"))), + .bind(NodeID::value))), Stm, Context); return findDeclMutation(Refs); } @@ -320,10 +363,10 @@ const Stmt *ExprMutationAnalyzer::findFunctionArgMutation(const Expr *Exp) { findAll(expr(anyOf(callExpr(NonConstRefParam, IsInstantiated, FuncDecl), cxxConstructExpr(NonConstRefParam, IsInstantiated, FuncDecl))) - .bind("expr")), + .bind(NodeID::value)), Stm, Context); for (const auto &Nodes : Matches) { - const auto *Exp = Nodes.getNodeAs("expr"); + const auto *Exp = Nodes.getNodeAs(NodeID::value); const auto *Func = Nodes.getNodeAs("func"); if (!Func->getBody()) return Exp; -- 2.7.4