diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp index b22f7ee87f74..219fc28595e5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp @@ -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(&P)) { @@ -91,20 +92,20 @@ 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(D) || isa(D)) { - const NamedDecl *ND = cast(D); - output << *ND; - } - else if (isa(D)) { - output << "block(line:" << Loc.getLine() << ":col:" << Loc.getColumn(); - } + if (isa(D) || isa(D)) { + const NamedDecl *ND = cast(D); + output << *ND; + } + else if (isa(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,10 +124,14 @@ 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(&CE)) - B.EmitBasicReport("Bailout Point", "Internal Statistics", "The analyzer " - "stopped analyzing at this point", + if (const CFGStmt *CS = dyn_cast(&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)); + } } }