[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.

llvm-svn: 153532
This commit is contained in:
Anna Zaks 2012-03-27 20:02:44 +00:00
parent 23df6bb18f
commit dc36e616a4
1 changed files with 20 additions and 15 deletions

View File

@ -48,7 +48,8 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
// 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 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
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,8 +92,8 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
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);
@ -101,10 +102,10 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
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 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
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,12 +124,16 @@ void AnalyzerStatsChecker::checkEndAnalysis(ExplodedGraph &G,
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));
}
}
}
void ento::registerAnalyzerStatsChecker(CheckerManager &mgr) {
mgr.registerChecker<AnalyzerStatsChecker>();