From: Ted Kremenek Date: Tue, 18 Sep 2007 20:59:00 +0000 (+0000) Subject: Added member template CFG::VisitBlockStmts to provide a succinct way X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a90b0d1e585d993621a342d0b2874e61941372d5;p=clang Added member template CFG::VisitBlockStmts to provide a succinct way of visiting all block-level statements in a CFG. Tightened implementation of UninitializedValues. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42106 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/UninitializedValues.cpp b/Analysis/UninitializedValues.cpp index c472b3a846..56897e67d4 100644 --- a/Analysis/UninitializedValues.cpp +++ b/Analysis/UninitializedValues.cpp @@ -51,28 +51,17 @@ public: Visit(E); } - void VisitDeclRefExpr(DeclRefExpr* DR) { - VisitDeclChain(DR->getDecl()); - } - - void VisitDeclStmt(DeclStmt* S) { - VisitDeclChain(S->getDecl()); - } - - void VisitStmt(Stmt* S) { - VisitChildren(S); - } - + void VisitDeclRefExpr(DeclRefExpr* DR) { VisitDeclChain(DR->getDecl()); } + void VisitDeclStmt(DeclStmt* S) { VisitDeclChain(S->getDecl()); } + void VisitStmt(Stmt* S) { VisitChildren(S); } + void operator()(Stmt* S) { BlockStmt_Visit(S); } }; } // end anonymous namespace void UninitializedValues::InitializeValues(const CFG& cfg) { RegisterDeclsAndExprs R(this->getAnalysisData()); - - for (CFG::const_iterator I=cfg.begin(), E=cfg.end(); I!=E; ++I) - for (CFGBlock::const_iterator BI=I->begin(), BE=I->end(); BI!=BE; ++BI) - R.BlockStmt_Visit(*BI); + cfg.VisitBlockStmts(R); } //===----------------------------------------------------------------------===// @@ -234,31 +223,22 @@ bool TransferFuncs::BlockStmt_VisitExpr(Expr* E) { // // Merges take the opposite approach. // -// In the merge of dataflow values (for Decls) we prefer unsoundness, and +// In the merge of dataflow values we prefer unsoundness, and // prefer false negatives to false positives. At merges, if a value for a // tracked Decl is EVER initialized in any of the predecessors we treat it as // initialized at the confluence point. -// -// For tracked CFGBlock-level expressions (such as the result of -// short-circuit), we do the opposite merge: if a value is EVER uninitialized -// in a predecessor we treat it as uninitalized at the confluence point. -// The reason we do this is because dataflow values for tracked Exprs are -// not as control-dependent as dataflow values for tracked Decls. //===----------------------------------------------------------------------===// namespace { struct Merge { void operator()(UninitializedValues::ValTy& Dst, UninitializedValues::ValTy& Src) { - assert (Dst.DeclBV.size() == Src.DeclBV.size() - && "Bitvector sizes do not match."); - - Dst.DeclBV |= Src.DeclBV; + assert (Dst.DeclBV.size() == Src.DeclBV.size() && "BV sizes do not match."); + assert (Dst.ExprBV.size() == Src.ExprBV.size() && "BV sizes do not match."); - assert (Dst.ExprBV.size() == Src.ExprBV.size() - && "Bitvector sizes do not match."); + Dst.DeclBV |= Src.DeclBV; + Dst.ExprBV |= Src.ExprBV; - Dst.ExprBV &= Src.ExprBV; } }; } // end anonymous namespace diff --git a/include/clang/AST/CFG.h b/include/clang/AST/CFG.h index 5734f96df1..5a3bbf21d0 100644 --- a/include/clang/AST/CFG.h +++ b/include/clang/AST/CFG.h @@ -248,6 +248,17 @@ public: bool operator!=(const Edge& RHS) const { return !(*this == RHS); } }; + //===--------------------------------------------------------------------===// + // Member templates useful for various batch operations over CFGs. + //===--------------------------------------------------------------------===// + + template + void VisitBlockStmts(CALLBACK& O) const { + for (const_iterator I=begin(), E=end(); I != E; ++I) + for (CFGBlock::const_iterator BI=I->begin(), BE=I->end(); BI != BE; ++BI) + O(*BI); + } + //===--------------------------------------------------------------------===// // CFG Introspection. //===--------------------------------------------------------------------===//