diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Analysis/CFG.cpp | 115 | ||||
-rw-r--r-- | clang/lib/Analysis/UninitializedValues.cpp | 2 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp | 37 |
3 files changed, 18 insertions, 136 deletions
diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 6eb84ce92c8..674c01201d2 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -3400,113 +3400,6 @@ bool CFGImplicitDtor::isNoReturn(ASTContext &astContext) const { } //===----------------------------------------------------------------------===// -// CFG: Queries for BlkExprs. -//===----------------------------------------------------------------------===// - -namespace { - typedef llvm::DenseMap<const Stmt*,unsigned> BlkExprMapTy; -} - -static void FindSubExprAssignments(const Stmt *S, - llvm::SmallPtrSet<const Expr*,50>& Set) { - if (!S) - return; - - for (Stmt::const_child_range I = S->children(); I; ++I) { - const Stmt *child = *I; - if (!child) - continue; - - if (const BinaryOperator* B = dyn_cast<BinaryOperator>(child)) - if (B->isAssignmentOp()) Set.insert(B); - - FindSubExprAssignments(child, Set); - } -} - -static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) { - BlkExprMapTy* M = new BlkExprMapTy(); - - // Look for assignments that are used as subexpressions. These are the only - // assignments that we want to *possibly* register as a block-level - // expression. Basically, if an assignment occurs both in a subexpression and - // at the block-level, it is a block-level expression. - llvm::SmallPtrSet<const Expr*,50> SubExprAssignments; - - for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) - for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) - if (Optional<CFGStmt> S = BI->getAs<CFGStmt>()) - FindSubExprAssignments(S->getStmt(), SubExprAssignments); - - for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) { - - // Iterate over the statements again on identify the Expr* and Stmt* at the - // block-level that are block-level expressions. - - for (CFGBlock::iterator BI=(*I)->begin(), EI=(*I)->end(); BI != EI; ++BI) { - Optional<CFGStmt> CS = BI->getAs<CFGStmt>(); - if (!CS) - continue; - if (const Expr *Exp = dyn_cast<Expr>(CS->getStmt())) { - assert((Exp->IgnoreParens() == Exp) && "No parens on block-level exps"); - - if (const BinaryOperator* B = dyn_cast<BinaryOperator>(Exp)) { - // Assignment expressions that are not nested within another - // expression are really "statements" whose value is never used by - // another expression. - if (B->isAssignmentOp() && !SubExprAssignments.count(Exp)) - continue; - } else if (const StmtExpr *SE = dyn_cast<StmtExpr>(Exp)) { - // Special handling for statement expressions. The last statement in - // the statement expression is also a block-level expr. - const CompoundStmt *C = SE->getSubStmt(); - if (!C->body_empty()) { - const Stmt *Last = C->body_back(); - if (const Expr *LastEx = dyn_cast<Expr>(Last)) - Last = LastEx->IgnoreParens(); - unsigned x = M->size(); - (*M)[Last] = x; - } - } - - unsigned x = M->size(); - (*M)[Exp] = x; - } - } - - // Look at terminators. The condition is a block-level expression. - - Stmt *S = (*I)->getTerminatorCondition(); - - if (S && M->find(S) == M->end()) { - unsigned x = M->size(); - (*M)[S] = x; - } - } - - return M; -} - -CFG::BlkExprNumTy CFG::getBlkExprNum(const Stmt *S) { - assert(S != NULL); - if (!BlkExprMap) { BlkExprMap = (void*) PopulateBlkExprMap(*this); } - - BlkExprMapTy* M = reinterpret_cast<BlkExprMapTy*>(BlkExprMap); - BlkExprMapTy::iterator I = M->find(S); - return (I == M->end()) ? CFG::BlkExprNumTy() : CFG::BlkExprNumTy(I->second); -} - -unsigned CFG::getNumBlkExprs() { - if (const BlkExprMapTy* M = reinterpret_cast<const BlkExprMapTy*>(BlkExprMap)) - return M->size(); - - // We assume callers interested in the number of BlkExprs will want - // the map constructed if it doesn't already exist. - BlkExprMap = (void*) PopulateBlkExprMap(*this); - return reinterpret_cast<BlkExprMapTy*>(BlkExprMap)->size(); -} - -//===----------------------------------------------------------------------===// // Filtered walking of the CFG. //===----------------------------------------------------------------------===// @@ -3530,14 +3423,6 @@ bool CFGBlock::FilterEdge(const CFGBlock::FilterOptions &F, } //===----------------------------------------------------------------------===// -// Cleanup: CFG dstor. -//===----------------------------------------------------------------------===// - -CFG::~CFG() { - delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap); -} - -//===----------------------------------------------------------------------===// // CFG pretty printing //===----------------------------------------------------------------------===// diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp index 730aa6ba212..3d155c8174a 100644 --- a/clang/lib/Analysis/UninitializedValues.cpp +++ b/clang/lib/Analysis/UninitializedValues.cpp @@ -14,12 +14,12 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" +#include "clang/AST/StmtVisitor.h" #include "clang/Analysis/Analyses/PostOrderCFGView.h" #include "clang/Analysis/Analyses/UninitializedValues.h" #include "clang/Analysis/AnalysisContext.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" -#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PackedVector.h" diff --git a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp index f336a6e6805..7c44c217061 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp @@ -18,7 +18,6 @@ #include "clang/AST/ParentMap.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Analysis/Analyses/LiveVariables.h" -#include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -391,26 +390,24 @@ public: //===----------------------------------------------------------------------===// namespace { -class FindEscaped : public CFGRecStmtDeclVisitor<FindEscaped>{ - CFG *cfg; +class FindEscaped { public: - FindEscaped(CFG *c) : cfg(c) {} - - CFG& getCFG() { return *cfg; } - llvm::SmallPtrSet<const VarDecl*, 20> Escaped; - void VisitUnaryOperator(UnaryOperator* U) { - // Check for '&'. Any VarDecl whose value has its address-taken we - // treat as escaped. - Expr *E = U->getSubExpr()->IgnoreParenCasts(); - if (U->getOpcode() == UO_AddrOf) - if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) - if (VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { - Escaped.insert(VD); - return; - } - Visit(E); + void operator()(const Stmt *S) { + // Check for '&'. Any VarDecl whose address has been taken we treat as + // escaped. + // FIXME: What about references? + const UnaryOperator *U = dyn_cast<UnaryOperator>(S); + if (!U) + return; + if (U->getOpcode() != UO_AddrOf) + return; + + const Expr *E = U->getSubExpr()->IgnoreParenCasts(); + if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) + if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) + Escaped.insert(VD); } }; } // end anonymous namespace @@ -438,8 +435,8 @@ public: CFG &cfg = *mgr.getCFG(D); AnalysisDeclContext *AC = mgr.getAnalysisDeclContext(D); ParentMap &pmap = mgr.getParentMap(D); - FindEscaped FS(&cfg); - FS.getCFG().VisitBlockStmts(FS); + FindEscaped FS; + cfg.VisitBlockStmts(FS); DeadStoreObs A(cfg, BR.getContext(), BR, AC, pmap, FS.Escaped); L->runOnAllBlocks(A); } |