19 #include "llvm/ADT/SmallPtrSet.h" 20 #include "llvm/ADT/SmallString.h" 21 #include "llvm/ADT/Statistic.h" 22 #include "llvm/Support/raw_ostream.h" 24 using namespace clang;
27 #define DEBUG_TYPE "StatsChecker" 30 "The # of blocks in top level functions");
32 "The # of unreachable blocks in analyzing top level functions");
35 class AnalyzerStatsChecker :
public Checker<check::EndAnalysis> {
37 void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng)
const;
41 void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
43 ExprEngine &Eng)
const {
44 const CFG *C =
nullptr;
46 llvm::SmallPtrSet<const CFGBlock*, 32> reachable;
49 const ExplodedNode *GraphRoot = *G.roots_begin();
50 const LocationContext *LC = GraphRoot->getLocation().getLocationContext();
56 I != G.nodes_end(); ++I) {
72 unsigned total = 0, unreachable = 0;
79 if (!reachable.count(CB)) {
92 llvm::raw_svector_ostream output(buf);
97 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
101 else if (isa<BlockDecl>(D)) {
105 NumBlocksUnreachable += unreachable;
107 std::string NameOfRootFunction = output.str();
109 output <<
" -> Total CFGBlocks: " << total <<
" | Unreachable CFGBlocks: " 110 << unreachable <<
" | Exhausted Block: " 111 << (Eng.wasBlocksExhausted() ?
"yes" :
"no")
112 <<
" | Empty WorkList: " 113 << (Eng.hasEmptyWorkList() ?
"yes" :
"no");
115 B.EmitBasicReport(D,
this,
"Analyzer Statistics",
"Internal Statistics",
116 output.str(), PathDiagnosticLocation(D, SM));
119 typedef CoreEngine::BlocksExhausted::const_iterator ExhaustedIterator;
120 const CoreEngine &CE = Eng.getCoreEngine();
121 for (ExhaustedIterator I = CE.blocks_exhausted_begin(),
122 E = CE.blocks_exhausted_end(); I != E; ++I) {
130 llvm::raw_svector_ostream outputI(bufI);
131 outputI <<
"(" << NameOfRootFunction <<
")" <<
132 ": The analyzer generated a sink at this point";
134 D,
this,
"Sink Point",
"Internal Statistics", outputI.str(),
140 void ento::registerAnalyzerStatsChecker(CheckerManager &mgr) {
141 mgr.registerChecker<AnalyzerStatsChecker>();
Defines the SourceManager interface.
Decl - This represents one declaration (or definition), e.g.
STATISTIC(NumBlocks, "The # of blocks in top level functions")
CFGBlockListTy::const_iterator const_iterator
Represents a single basic block in a source-level CFG.
AllNodesTy::iterator node_iterator
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
unsigned getLine() const
Return the presumed line number of this location.
const CFGBlock * getDst() const
Represents an unpacked "presumed" location which can be presented to the user.
static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)
Create a location for the beginning of the declaration.
unsigned getColumn() const
Return the presumed column number of this location.
Optional< T > getAs() const
Convert to the specified CFGElement type, returning None if this CFGElement is not of the desired typ...
Dataflow Directional Tag Classes.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
const Decl * getDecl() const
const LocationContext * getLocationContext() const
Represents a top-level expression in a basic block.
This represents a decl that may have a name.
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
This class handles loading and caching of source files into memory.
SourceLocation getLocation() const