[analyzer] Stats checker: minor interprocedural tweaks.
Report root function name with exhausted block diagnostic.
Also, use stack frames, not just any location context when checking if
the basic block is in the same context.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153532 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
index b22f7ee..219fc28 100644
--- a/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
@@ -48,7 +48,8 @@
// Root node should have the location context of the top most function.
const ExplodedNode *GraphRoot = *G.roots_begin();
- const LocationContext *LC = GraphRoot->getLocation().getLocationContext();
+ const LocationContext *LC =
+ GraphRoot->getLocation().getLocationContext()->getCurrentStackFrame();
// Iterate over the exploded graph.
for (ExplodedGraph::node_iterator I = G.nodes_begin();
@@ -56,7 +57,7 @@
const ProgramPoint &P = I->getLocation();
// Only check the coverage in the top level function.
- if (LC != P.getLocationContext())
+ if (LC != P.getLocationContext()->getCurrentStackFrame())
continue;
if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
@@ -91,20 +92,20 @@
SmallString<128> buf;
llvm::raw_svector_ostream output(buf);
PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
- if (Loc.isValid()) {
- output << Loc.getFilename() << " : ";
+ if (!Loc.isValid())
+ return;
- if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
- const NamedDecl *ND = cast<NamedDecl>(D);
- output << *ND;
- }
- else if (isa<BlockDecl>(D)) {
- output << "block(line:" << Loc.getLine() << ":col:" << Loc.getColumn();
- }
+ if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
+ const NamedDecl *ND = cast<NamedDecl>(D);
+ output << *ND;
+ }
+ else if (isa<BlockDecl>(D)) {
+ output << "block(line:" << Loc.getLine() << ":col:" << Loc.getColumn();
}
NumBlocksUnreachable += unreachable;
NumBlocks += total;
+ std::string NameOfRootFunction = output.str();
output << " -> Total CFGBlocks: " << total << " | Unreachable CFGBlocks: "
<< unreachable << " | Exhausted Block: "
@@ -115,7 +116,7 @@
B.EmitBasicReport("Analyzer Statistics", "Internal Statistics", output.str(),
PathDiagnosticLocation(D, SM));
- // Emit warning for each block we bailed out on
+ // Emit warning for each block we bailed out on.
typedef CoreEngine::BlocksExhausted::const_iterator ExhaustedIterator;
const CoreEngine &CE = Eng.getCoreEngine();
for (ExhaustedIterator I = CE.blocks_exhausted_begin(),
@@ -123,10 +124,14 @@
const BlockEdge &BE = I->first;
const CFGBlock *Exit = BE.getDst();
const CFGElement &CE = Exit->front();
- if (const CFGStmt *CS = dyn_cast<CFGStmt>(&CE))
- B.EmitBasicReport("Bailout Point", "Internal Statistics", "The analyzer "
- "stopped analyzing at this point",
+ if (const CFGStmt *CS = dyn_cast<CFGStmt>(&CE)) {
+ SmallString<128> bufI;
+ llvm::raw_svector_ostream outputI(bufI);
+ outputI << "(" << NameOfRootFunction << ")" <<
+ ": The analyzer generated a sink at this point";
+ B.EmitBasicReport("Sink Point", "Internal Statistics", outputI.str(),
PathDiagnosticLocation::createBegin(CS->getStmt(), SM, LC));
+ }
}
}