18 #include "llvm/ADT/SmallPtrSet.h" 19 #include "llvm/ADT/SmallString.h" 20 #include "llvm/ADT/Statistic.h" 21 #include "llvm/Support/raw_ostream.h" 23 using namespace clang;
26 #define DEBUG_TYPE "StatsChecker" 29 "The # of blocks in top level functions");
31 "The # of unreachable blocks in analyzing top level functions");
34 class AnalyzerStatsChecker :
public Checker<check::EndAnalysis> {
36 void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng)
const;
40 void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
42 ExprEngine &Eng)
const {
43 const CFG *C =
nullptr;
45 llvm::SmallPtrSet<const CFGBlock*, 32> reachable;
48 const ExplodedNode *GraphRoot = *G.roots_begin();
49 const LocationContext *LC = GraphRoot->getLocation().getLocationContext();
55 I != G.nodes_end(); ++I) {
71 unsigned total = 0, unreachable = 0;
78 if (!reachable.count(CB)) {
91 llvm::raw_svector_ostream output(buf);
96 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
100 else if (isa<BlockDecl>(D)) {
104 NumBlocksUnreachable += unreachable;
106 std::string NameOfRootFunction = output.str();
108 output <<
" -> Total CFGBlocks: " << total <<
" | Unreachable CFGBlocks: " 109 << unreachable <<
" | Exhausted Block: " 110 << (Eng.wasBlocksExhausted() ?
"yes" :
"no")
111 <<
" | Empty WorkList: " 112 << (Eng.hasEmptyWorkList() ?
"yes" :
"no");
114 B.EmitBasicReport(D,
this,
"Analyzer Statistics",
"Internal Statistics",
115 output.str(), PathDiagnosticLocation(D, SM));
118 typedef CoreEngine::BlocksExhausted::const_iterator ExhaustedIterator;
119 const CoreEngine &CE = Eng.getCoreEngine();
120 for (ExhaustedIterator I = CE.blocks_exhausted_begin(),
121 E = CE.blocks_exhausted_end(); I != E; ++I) {
129 llvm::raw_svector_ostream outputI(bufI);
130 outputI <<
"(" << NameOfRootFunction <<
")" <<
131 ": The analyzer generated a sink at this point";
133 D,
this,
"Sink Point",
"Internal Statistics", outputI.str(),
139 void ento::registerAnalyzerStatsChecker(CheckerManager &mgr) {
140 mgr.registerChecker<AnalyzerStatsChecker>();
143 bool ento::shouldRegisterAnalyzerStatsChecker(
const LangOptions &LO) {
Defines the SourceManager interface.
Decl - This represents one declaration (or definition), e.g.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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