diff options
Diffstat (limited to 'lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp | 156 |
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); -} |