summaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp')
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp156
1 files changed, 13 insertions, 143 deletions
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 44abde5da6d11..d87937d9b63df 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -50,8 +50,6 @@ using namespace ento;
#define DEBUG_TYPE "AnalysisConsumer"
-static std::unique_ptr<ExplodedNode::Auditor> CreateUbiViz();
-
STATISTIC(NumFunctionTopLevel, "The # of functions at top level.");
STATISTIC(NumFunctionsAnalyzed,
"The # of functions and blocks analyzed (as top level "
@@ -206,7 +204,7 @@ public:
PP(CI.getPreprocessor()), OutDir(outdir), Opts(std::move(opts)),
Plugins(plugins), Injector(injector), CTU(CI) {
DigestAnalyzerOptions();
- if (Opts->PrintStats || Opts->shouldSerializeStats()) {
+ if (Opts->PrintStats || Opts->ShouldSerializeStats) {
AnalyzerTimers = llvm::make_unique<llvm::TimerGroup>(
"analyzer", "Analyzer timers");
TUTotalTimer = llvm::make_unique<llvm::Timer>(
@@ -295,13 +293,12 @@ public:
void Initialize(ASTContext &Context) override {
Ctx = &Context;
- checkerMgr =
- createCheckerManager(*Opts, PP.getLangOpts(), Plugins,
- CheckerRegistrationFns, PP.getDiagnostics());
+ checkerMgr = createCheckerManager(
+ *Ctx, *Opts, Plugins, CheckerRegistrationFns, PP.getDiagnostics());
Mgr = llvm::make_unique<AnalysisManager>(
- *Ctx, PP.getDiagnostics(), PP.getLangOpts(), PathConsumers,
- CreateStoreMgr, CreateConstraintMgr, checkerMgr.get(), *Opts, Injector);
+ *Ctx, PP.getDiagnostics(), PathConsumers, CreateStoreMgr,
+ CreateConstraintMgr, checkerMgr.get(), *Opts, Injector);
}
/// Store the top level decls in the set to be processed later on.
@@ -334,9 +331,6 @@ public:
void RunPathSensitiveChecks(Decl *D,
ExprEngine::InliningModes IMode,
SetOfConstDecls *VisitedCallees);
- void ActionExprEngine(Decl *D, bool ObjCGCEnabled,
- ExprEngine::InliningModes IMode,
- SetOfConstDecls *VisitedCallees);
/// Visitors for the RecursiveASTVisitor.
bool shouldWalkTypesOfTypeLocs() const { return false; }
@@ -682,7 +676,7 @@ AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) {
// - System headers: don't run any checks.
SourceManager &SM = Ctx->getSourceManager();
const Stmt *Body = D->getBody();
- SourceLocation SL = Body ? Body->getLocStart() : D->getLocation();
+ SourceLocation SL = Body ? Body->getBeginLoc() : D->getLocation();
SL = SM.getExpansionLoc(SL);
if (!Opts->AnalyzeAll && !Mgr->isInCodeFile(SL)) {
@@ -729,9 +723,9 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
// Path-sensitive checking.
//===----------------------------------------------------------------------===//
-void AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled,
- ExprEngine::InliningModes IMode,
- SetOfConstDecls *VisitedCallees) {
+void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
+ ExprEngine::InliningModes IMode,
+ SetOfConstDecls *VisitedCallees) {
// Construct the analysis engine. First check if the CFG is valid.
// FIXME: Inter-procedural analysis will need to handle invalid CFGs.
if (!Mgr->getCFG(D))
@@ -741,23 +735,14 @@ void AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled,
if (!Mgr->getAnalysisDeclContext(D)->getAnalysis<RelaxedLiveVariables>())
return;
- ExprEngine Eng(CTU, *Mgr, ObjCGCEnabled, VisitedCallees, &FunctionSummaries,
- IMode);
-
- // Set the graph auditor.
- std::unique_ptr<ExplodedNode::Auditor> Auditor;
- if (Mgr->options.visualizeExplodedGraphWithUbiGraph) {
- Auditor = CreateUbiViz();
- ExplodedNode::SetAuditor(Auditor.get());
- }
+ ExprEngine Eng(CTU, *Mgr, VisitedCallees, &FunctionSummaries, IMode);
// Execute the worklist algorithm.
Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
- Mgr->options.getMaxNodesPerTopLevelFunction());
+ Mgr->options.MaxNodesPerTopLevelFunction);
- // Release the auditor (if any) so that it doesn't monitor the graph
- // created BugReporter.
- ExplodedNode::SetAuditor(nullptr);
+ if (!Mgr->options.DumpExplodedGraphTo.empty())
+ Eng.DumpGraph(Mgr->options.TrimGraph, Mgr->options.DumpExplodedGraphTo);
// Visualize the exploded graph.
if (Mgr->options.visualizeExplodedGraphWithGraphViz)
@@ -767,26 +752,6 @@ void AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled,
Eng.getBugReporter().FlushReports();
}
-void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
- ExprEngine::InliningModes IMode,
- SetOfConstDecls *Visited) {
-
- switch (Mgr->getLangOpts().getGC()) {
- case LangOptions::NonGC:
- ActionExprEngine(D, false, IMode, Visited);
- break;
-
- case LangOptions::GCOnly:
- ActionExprEngine(D, true, IMode, Visited);
- break;
-
- case LangOptions::HybridGC:
- ActionExprEngine(D, false, IMode, Visited);
- ActionExprEngine(D, true, IMode, Visited);
- break;
- }
-}
-
//===----------------------------------------------------------------------===//
// AnalysisConsumer creation.
//===----------------------------------------------------------------------===//
@@ -804,98 +769,3 @@ ento::CreateAnalysisConsumer(CompilerInstance &CI) {
CI.getFrontendOpts().Plugins,
hasModelPath ? new ModelInjector(CI) : nullptr);
}
-
-//===----------------------------------------------------------------------===//
-// Ubigraph Visualization. FIXME: Move to separate file.
-//===----------------------------------------------------------------------===//
-
-namespace {
-
-class UbigraphViz : public ExplodedNode::Auditor {
- std::unique_ptr<raw_ostream> Out;
- std::string Filename;
- unsigned Cntr;
-
- typedef llvm::DenseMap<void*,unsigned> VMap;
- VMap M;
-
-public:
- UbigraphViz(std::unique_ptr<raw_ostream> Out, StringRef Filename);
-
- ~UbigraphViz() override;
-
- void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) override;
-};
-
-} // end anonymous namespace
-
-static std::unique_ptr<ExplodedNode::Auditor> CreateUbiViz() {
- SmallString<128> P;
- int FD;
- llvm::sys::fs::createTemporaryFile("llvm_ubi", "", FD, P);
- llvm::errs() << "Writing '" << P << "'.\n";
-
- auto Stream = llvm::make_unique<llvm::raw_fd_ostream>(FD, true);
-
- return llvm::make_unique<UbigraphViz>(std::move(Stream), P);
-}
-
-void UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) {
-
- assert (Src != Dst && "Self-edges are not allowed.");
-
- // Lookup the Src. If it is a new node, it's a root.
- VMap::iterator SrcI= M.find(Src);
- unsigned SrcID;
-
- if (SrcI == M.end()) {
- M[Src] = SrcID = Cntr++;
- *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n";
- }
- else
- SrcID = SrcI->second;
-
- // Lookup the Dst.
- VMap::iterator DstI= M.find(Dst);
- unsigned DstID;
-
- if (DstI == M.end()) {
- M[Dst] = DstID = Cntr++;
- *Out << "('vertex', " << DstID << ")\n";
- }
- else {
- // We have hit DstID before. Change its style to reflect a cache hit.
- DstID = DstI->second;
- *Out << "('change_vertex_style', " << DstID << ", 1)\n";
- }
-
- // Add the edge.
- *Out << "('edge', " << SrcID << ", " << DstID
- << ", ('arrow','true'), ('oriented', 'true'))\n";
-}
-
-UbigraphViz::UbigraphViz(std::unique_ptr<raw_ostream> OutStream,
- StringRef Filename)
- : Out(std::move(OutStream)), Filename(Filename), Cntr(0) {
-
- *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n";
- *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66'),"
- " ('size', '1.5'))\n";
-}
-
-UbigraphViz::~UbigraphViz() {
- Out.reset();
- llvm::errs() << "Running 'ubiviz' program... ";
- std::string ErrMsg;
- std::string Ubiviz;
- if (auto Path = llvm::sys::findProgramByName("ubiviz"))
- Ubiviz = *Path;
- std::array<StringRef, 2> Args{{Ubiviz, Filename}};
-
- if (llvm::sys::ExecuteAndWait(Ubiviz, Args, llvm::None, {}, 0, 0, &ErrMsg)) {
- llvm::errs() << "Error viewing graph: " << ErrMsg << "\n";
- }
-
- // Delete the file.
- llvm::sys::fs::remove(Filename);
-}