1 //===--- AnalysisConsumer.cpp - ASTConsumer for running Analyses ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // "Meta" ASTConsumer for running different source analyses.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
14 #include "ModelInjector.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/RecursiveASTVisitor.h"
19 #include "clang/Analysis/Analyses/LiveVariables.h"
20 #include "clang/Analysis/CFG.h"
21 #include "clang/Analysis/CallGraph.h"
22 #include "clang/Analysis/CodeInjector.h"
23 #include "clang/Analysis/PathDiagnostic.h"
24 #include "clang/Basic/SourceManager.h"
25 #include "clang/CrossTU/CrossTranslationUnit.h"
26 #include "clang/Frontend/CompilerInstance.h"
27 #include "clang/Lex/Preprocessor.h"
28 #include "clang/Rewrite/Core/Rewriter.h"
29 #include "clang/StaticAnalyzer/Checkers/LocalCheckers.h"
30 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
31 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
32 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
33 #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h"
34 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
35 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
36 #include "clang/StaticAnalyzer/Frontend/CheckerRegistration.h"
37 #include "clang/Tooling/Core/Replacement.h"
38 #include "clang/Tooling/Tooling.h"
39 #include "llvm/ADT/PostOrderIterator.h"
40 #include "llvm/ADT/Statistic.h"
41 #include "llvm/Support/FileSystem.h"
42 #include "llvm/Support/Path.h"
43 #include "llvm/Support/Program.h"
44 #include "llvm/Support/Timer.h"
45 #include "llvm/Support/raw_ostream.h"
46 #include <memory>
47 #include <queue>
48 #include <utility>
49 
50 using namespace clang;
51 using namespace ento;
52 using namespace tooling;
53 
54 #define DEBUG_TYPE "AnalysisConsumer"
55 
56 STATISTIC(NumFunctionTopLevel, "The # of functions at top level.");
57 STATISTIC(NumFunctionsAnalyzed,
58                       "The # of functions and blocks analyzed (as top level "
59                       "with inlining turned on).");
60 STATISTIC(NumBlocksInAnalyzedFunctions,
61                       "The # of basic blocks in the analyzed functions.");
62 STATISTIC(NumVisitedBlocksInAnalyzedFunctions,
63           "The # of visited basic blocks in the analyzed functions.");
64 STATISTIC(PercentReachableBlocks, "The % of reachable basic blocks.");
65 STATISTIC(MaxCFGSize, "The maximum number of basic blocks in a function.");
66 
67 //===----------------------------------------------------------------------===//
68 // Special PathDiagnosticConsumers.
69 //===----------------------------------------------------------------------===//
70 
71 void ento::createPlistHTMLDiagnosticConsumer(
72     AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
73     const std::string &prefix, const Preprocessor &PP,
74     const cross_tu::CrossTranslationUnitContext &CTU) {
75   createHTMLDiagnosticConsumer(
76       AnalyzerOpts, C, std::string(llvm::sys::path::parent_path(prefix)), PP,
77       CTU);
78   createPlistMultiFileDiagnosticConsumer(AnalyzerOpts, C, prefix, PP, CTU);
79 }
80 
81 void ento::createTextPathDiagnosticConsumer(
82     AnalyzerOptions &AnalyzerOpts, PathDiagnosticConsumers &C,
83     const std::string &Prefix, const clang::Preprocessor &PP,
84     const cross_tu::CrossTranslationUnitContext &CTU) {
85   llvm_unreachable("'text' consumer should be enabled on ClangDiags");
86 }
87 
88 namespace {
89 class ClangDiagPathDiagConsumer : public PathDiagnosticConsumer {
90   DiagnosticsEngine &Diag;
91   LangOptions LO;
92 
93   bool IncludePath = false;
94   bool ShouldEmitAsError = false;
95   bool ApplyFixIts = false;
96 
97 public:
98   ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag, LangOptions LO)
99       : Diag(Diag), LO(LO) {}
100   ~ClangDiagPathDiagConsumer() override {}
101   StringRef getName() const override { return "ClangDiags"; }
102 
103   bool supportsLogicalOpControlFlow() const override { return true; }
104   bool supportsCrossFileDiagnostics() const override { return true; }
105 
106   PathGenerationScheme getGenerationScheme() const override {
107     return IncludePath ? Minimal : None;
108   }
109 
110   void enablePaths() { IncludePath = true; }
111   void enableWerror() { ShouldEmitAsError = true; }
112   void enableApplyFixIts() { ApplyFixIts = true; }
113 
114   void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
115                             FilesMade *filesMade) override {
116     unsigned WarnID =
117         ShouldEmitAsError
118             ? Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0")
119             : Diag.getCustomDiagID(DiagnosticsEngine::Warning, "%0");
120     unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note, "%0");
121     SourceManager &SM = Diag.getSourceManager();
122 
123     Replacements Repls;
124     auto reportPiece = [&](unsigned ID, FullSourceLoc Loc, StringRef String,
125                            ArrayRef<SourceRange> Ranges,
126                            ArrayRef<FixItHint> Fixits) {
127       if (!ApplyFixIts) {
128         Diag.Report(Loc, ID) << String << Ranges << Fixits;
129         return;
130       }
131 
132       Diag.Report(Loc, ID) << String << Ranges;
133       for (const FixItHint &Hint : Fixits) {
134         Replacement Repl(SM, Hint.RemoveRange, Hint.CodeToInsert);
135 
136         if (llvm::Error Err = Repls.add(Repl)) {
137           llvm::errs() << "Error applying replacement " << Repl.toString()
138                        << ": " << Err << "\n";
139         }
140       }
141     };
142 
143     for (std::vector<const PathDiagnostic *>::iterator I = Diags.begin(),
144          E = Diags.end();
145          I != E; ++I) {
146       const PathDiagnostic *PD = *I;
147       reportPiece(WarnID, PD->getLocation().asLocation(),
148                   PD->getShortDescription(), PD->path.back()->getRanges(),
149                   PD->path.back()->getFixits());
150 
151       // First, add extra notes, even if paths should not be included.
152       for (const auto &Piece : PD->path) {
153         if (!isa<PathDiagnosticNotePiece>(Piece.get()))
154           continue;
155 
156         reportPiece(NoteID, Piece->getLocation().asLocation(),
157                     Piece->getString(), Piece->getRanges(), Piece->getFixits());
158       }
159 
160       if (!IncludePath)
161         continue;
162 
163       // Then, add the path notes if necessary.
164       PathPieces FlatPath = PD->path.flatten(/*ShouldFlattenMacros=*/true);
165       for (const auto &Piece : FlatPath) {
166         if (isa<PathDiagnosticNotePiece>(Piece.get()))
167           continue;
168 
169         reportPiece(NoteID, Piece->getLocation().asLocation(),
170                     Piece->getString(), Piece->getRanges(), Piece->getFixits());
171       }
172     }
173 
174     if (!ApplyFixIts || Repls.empty())
175       return;
176 
177     Rewriter Rewrite(SM, LO);
178     if (!applyAllReplacements(Repls, Rewrite)) {
179       llvm::errs() << "An error occured during applying fix-it.\n";
180     }
181 
182     Rewrite.overwriteChangedFiles();
183   }
184 };
185 } // end anonymous namespace
186 
187 //===----------------------------------------------------------------------===//
188 // AnalysisConsumer declaration.
189 //===----------------------------------------------------------------------===//
190 
191 namespace {
192 
193 class AnalysisConsumer : public AnalysisASTConsumer,
194                          public RecursiveASTVisitor<AnalysisConsumer> {
195   enum {
196     AM_None = 0,
197     AM_Syntax = 0x1,
198     AM_Path = 0x2
199   };
200   typedef unsigned AnalysisMode;
201 
202   /// Mode of the analyzes while recursively visiting Decls.
203   AnalysisMode RecVisitorMode;
204   /// Bug Reporter to use while recursively visiting Decls.
205   BugReporter *RecVisitorBR;
206 
207   std::vector<std::function<void(CheckerRegistry &)>> CheckerRegistrationFns;
208 
209 public:
210   ASTContext *Ctx;
211   Preprocessor &PP;
212   const std::string OutDir;
213   AnalyzerOptionsRef Opts;
214   ArrayRef<std::string> Plugins;
215   CodeInjector *Injector;
216   cross_tu::CrossTranslationUnitContext CTU;
217 
218   /// Stores the declarations from the local translation unit.
219   /// Note, we pre-compute the local declarations at parse time as an
220   /// optimization to make sure we do not deserialize everything from disk.
221   /// The local declaration to all declarations ratio might be very small when
222   /// working with a PCH file.
223   SetOfDecls LocalTUDecls;
224 
225   // Set of PathDiagnosticConsumers.  Owned by AnalysisManager.
226   PathDiagnosticConsumers PathConsumers;
227 
228   StoreManagerCreator CreateStoreMgr;
229   ConstraintManagerCreator CreateConstraintMgr;
230 
231   std::unique_ptr<CheckerManager> checkerMgr;
232   std::unique_ptr<AnalysisManager> Mgr;
233 
234   /// Time the analyzes time of each translation unit.
235   std::unique_ptr<llvm::TimerGroup> AnalyzerTimers;
236   std::unique_ptr<llvm::Timer> SyntaxCheckTimer;
237   std::unique_ptr<llvm::Timer> ExprEngineTimer;
238   std::unique_ptr<llvm::Timer> BugReporterTimer;
239 
240   /// The information about analyzed functions shared throughout the
241   /// translation unit.
242   FunctionSummariesTy FunctionSummaries;
243 
244   AnalysisConsumer(CompilerInstance &CI, const std::string &outdir,
245                    AnalyzerOptionsRef opts, ArrayRef<std::string> plugins,
246                    CodeInjector *injector)
247       : RecVisitorMode(0), RecVisitorBR(nullptr), Ctx(nullptr),
248         PP(CI.getPreprocessor()), OutDir(outdir), Opts(std::move(opts)),
249         Plugins(plugins), Injector(injector), CTU(CI) {
250     DigestAnalyzerOptions();
251     if (Opts->PrintStats || Opts->ShouldSerializeStats) {
252       AnalyzerTimers = std::make_unique<llvm::TimerGroup>(
253           "analyzer", "Analyzer timers");
254       SyntaxCheckTimer = std::make_unique<llvm::Timer>(
255           "syntaxchecks", "Syntax-based analysis time", *AnalyzerTimers);
256       ExprEngineTimer = std::make_unique<llvm::Timer>(
257           "exprengine", "Path exploration time", *AnalyzerTimers);
258       BugReporterTimer = std::make_unique<llvm::Timer>(
259           "bugreporter", "Path-sensitive report post-processing time",
260           *AnalyzerTimers);
261       llvm::EnableStatistics(/* PrintOnExit= */ false);
262     }
263   }
264 
265   ~AnalysisConsumer() override {
266     if (Opts->PrintStats) {
267       llvm::PrintStatistics();
268     }
269   }
270 
271   void DigestAnalyzerOptions() {
272     if (Opts->AnalysisDiagOpt != PD_NONE) {
273       // Create the PathDiagnosticConsumer.
274       ClangDiagPathDiagConsumer *clangDiags =
275           new ClangDiagPathDiagConsumer(PP.getDiagnostics(), PP.getLangOpts());
276       PathConsumers.push_back(clangDiags);
277 
278       if (Opts->AnalyzerWerror)
279         clangDiags->enableWerror();
280 
281       if (Opts->ShouldApplyFixIts)
282         clangDiags->enableApplyFixIts();
283 
284       if (Opts->AnalysisDiagOpt == PD_TEXT) {
285         clangDiags->enablePaths();
286 
287       } else if (!OutDir.empty()) {
288         switch (Opts->AnalysisDiagOpt) {
289         default:
290 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)                    \
291   case PD_##NAME:                                                              \
292     CREATEFN(*Opts.get(), PathConsumers, OutDir, PP, CTU);                     \
293     break;
294 #include "clang/StaticAnalyzer/Core/Analyses.def"
295         }
296       }
297     }
298 
299     // Create the analyzer component creators.
300     switch (Opts->AnalysisStoreOpt) {
301     default:
302       llvm_unreachable("Unknown store manager.");
303 #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN)           \
304       case NAME##Model: CreateStoreMgr = CREATEFN; break;
305 #include "clang/StaticAnalyzer/Core/Analyses.def"
306     }
307 
308     switch (Opts->AnalysisConstraintsOpt) {
309     default:
310       llvm_unreachable("Unknown constraint manager.");
311 #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN)     \
312       case NAME##Model: CreateConstraintMgr = CREATEFN; break;
313 #include "clang/StaticAnalyzer/Core/Analyses.def"
314     }
315   }
316 
317   void DisplayFunction(const Decl *D, AnalysisMode Mode,
318                        ExprEngine::InliningModes IMode) {
319     if (!Opts->AnalyzerDisplayProgress)
320       return;
321 
322     SourceManager &SM = Mgr->getASTContext().getSourceManager();
323     PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
324     if (Loc.isValid()) {
325       llvm::errs() << "ANALYZE";
326 
327       if (Mode == AM_Syntax)
328         llvm::errs() << " (Syntax)";
329       else if (Mode == AM_Path) {
330         llvm::errs() << " (Path, ";
331         switch (IMode) {
332           case ExprEngine::Inline_Minimal:
333             llvm::errs() << " Inline_Minimal";
334             break;
335           case ExprEngine::Inline_Regular:
336             llvm::errs() << " Inline_Regular";
337             break;
338         }
339         llvm::errs() << ")";
340       }
341       else
342         assert(Mode == (AM_Syntax | AM_Path) && "Unexpected mode!");
343 
344       llvm::errs() << ": " << Loc.getFilename() << ' '
345                            << getFunctionName(D) << '\n';
346     }
347   }
348 
349   void Initialize(ASTContext &Context) override {
350     Ctx = &Context;
351     checkerMgr = createCheckerManager(
352         *Ctx, *Opts, Plugins, CheckerRegistrationFns, PP.getDiagnostics());
353 
354     Mgr = std::make_unique<AnalysisManager>(*Ctx, PP, PathConsumers,
355                                             CreateStoreMgr, CreateConstraintMgr,
356                                             checkerMgr.get(), *Opts, Injector);
357   }
358 
359   /// Store the top level decls in the set to be processed later on.
360   /// (Doing this pre-processing avoids deserialization of data from PCH.)
361   bool HandleTopLevelDecl(DeclGroupRef D) override;
362   void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override;
363 
364   void HandleTranslationUnit(ASTContext &C) override;
365 
366   /// Determine which inlining mode should be used when this function is
367   /// analyzed. This allows to redefine the default inlining policies when
368   /// analyzing a given function.
369   ExprEngine::InliningModes
370     getInliningModeForFunction(const Decl *D, const SetOfConstDecls &Visited);
371 
372   /// Build the call graph for all the top level decls of this TU and
373   /// use it to define the order in which the functions should be visited.
374   void HandleDeclsCallGraph(const unsigned LocalTUDeclsSize);
375 
376   /// Run analyzes(syntax or path sensitive) on the given function.
377   /// \param Mode - determines if we are requesting syntax only or path
378   /// sensitive only analysis.
379   /// \param VisitedCallees - The output parameter, which is populated with the
380   /// set of functions which should be considered analyzed after analyzing the
381   /// given root function.
382   void HandleCode(Decl *D, AnalysisMode Mode,
383                   ExprEngine::InliningModes IMode = ExprEngine::Inline_Minimal,
384                   SetOfConstDecls *VisitedCallees = nullptr);
385 
386   void RunPathSensitiveChecks(Decl *D,
387                               ExprEngine::InliningModes IMode,
388                               SetOfConstDecls *VisitedCallees);
389 
390   /// Visitors for the RecursiveASTVisitor.
391   bool shouldWalkTypesOfTypeLocs() const { return false; }
392 
393   /// Handle callbacks for arbitrary Decls.
394   bool VisitDecl(Decl *D) {
395     AnalysisMode Mode = getModeForDecl(D, RecVisitorMode);
396     if (Mode & AM_Syntax) {
397       if (SyntaxCheckTimer)
398         SyntaxCheckTimer->startTimer();
399       checkerMgr->runCheckersOnASTDecl(D, *Mgr, *RecVisitorBR);
400       if (SyntaxCheckTimer)
401         SyntaxCheckTimer->stopTimer();
402     }
403     return true;
404   }
405 
406   bool VisitVarDecl(VarDecl *VD) {
407     if (!Opts->IsNaiveCTUEnabled)
408       return true;
409 
410     if (VD->hasExternalStorage() || VD->isStaticDataMember()) {
411       if (!cross_tu::containsConst(VD, *Ctx))
412         return true;
413     } else {
414       // Cannot be initialized in another TU.
415       return true;
416     }
417 
418     if (VD->getAnyInitializer())
419       return true;
420 
421     llvm::Expected<const VarDecl *> CTUDeclOrError =
422       CTU.getCrossTUDefinition(VD, Opts->CTUDir, Opts->CTUIndexName,
423                                Opts->DisplayCTUProgress);
424 
425     if (!CTUDeclOrError) {
426       handleAllErrors(CTUDeclOrError.takeError(),
427                       [&](const cross_tu::IndexError &IE) {
428                         CTU.emitCrossTUDiagnostics(IE);
429                       });
430     }
431 
432     return true;
433   }
434 
435   bool VisitFunctionDecl(FunctionDecl *FD) {
436     IdentifierInfo *II = FD->getIdentifier();
437     if (II && II->getName().startswith("__inline"))
438       return true;
439 
440     // We skip function template definitions, as their semantics is
441     // only determined when they are instantiated.
442     if (FD->isThisDeclarationADefinition() &&
443         !FD->isDependentContext()) {
444       assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
445       HandleCode(FD, RecVisitorMode);
446     }
447     return true;
448   }
449 
450   bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
451     if (MD->isThisDeclarationADefinition()) {
452       assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
453       HandleCode(MD, RecVisitorMode);
454     }
455     return true;
456   }
457 
458   bool VisitBlockDecl(BlockDecl *BD) {
459     if (BD->hasBody()) {
460       assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
461       // Since we skip function template definitions, we should skip blocks
462       // declared in those functions as well.
463       if (!BD->isDependentContext()) {
464         HandleCode(BD, RecVisitorMode);
465       }
466     }
467     return true;
468   }
469 
470   void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) override {
471     PathConsumers.push_back(Consumer);
472   }
473 
474   void AddCheckerRegistrationFn(std::function<void(CheckerRegistry&)> Fn) override {
475     CheckerRegistrationFns.push_back(std::move(Fn));
476   }
477 
478 private:
479   void storeTopLevelDecls(DeclGroupRef DG);
480   std::string getFunctionName(const Decl *D);
481 
482   /// Check if we should skip (not analyze) the given function.
483   AnalysisMode getModeForDecl(Decl *D, AnalysisMode Mode);
484   void runAnalysisOnTranslationUnit(ASTContext &C);
485 
486   /// Print \p S to stderr if \c Opts->AnalyzerDisplayProgress is set.
487   void reportAnalyzerProgress(StringRef S);
488 };
489 } // end anonymous namespace
490 
491 
492 //===----------------------------------------------------------------------===//
493 // AnalysisConsumer implementation.
494 //===----------------------------------------------------------------------===//
495 bool AnalysisConsumer::HandleTopLevelDecl(DeclGroupRef DG) {
496   storeTopLevelDecls(DG);
497   return true;
498 }
499 
500 void AnalysisConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) {
501   storeTopLevelDecls(DG);
502 }
503 
504 void AnalysisConsumer::storeTopLevelDecls(DeclGroupRef DG) {
505   for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
506 
507     // Skip ObjCMethodDecl, wait for the objc container to avoid
508     // analyzing twice.
509     if (isa<ObjCMethodDecl>(*I))
510       continue;
511 
512     LocalTUDecls.push_back(*I);
513   }
514 }
515 
516 static bool shouldSkipFunction(const Decl *D,
517                                const SetOfConstDecls &Visited,
518                                const SetOfConstDecls &VisitedAsTopLevel) {
519   if (VisitedAsTopLevel.count(D))
520     return true;
521 
522   // Skip analysis of inheriting constructors as top-level functions. These
523   // constructors don't even have a body written down in the code, so even if
524   // we find a bug, we won't be able to display it.
525   if (const auto *CD = dyn_cast<CXXConstructorDecl>(D))
526     if (CD->isInheritingConstructor())
527       return true;
528 
529   // We want to re-analyse the functions as top level in the following cases:
530   // - The 'init' methods should be reanalyzed because
531   //   ObjCNonNilReturnValueChecker assumes that '[super init]' never returns
532   //   'nil' and unless we analyze the 'init' functions as top level, we will
533   //   not catch errors within defensive code.
534   // - We want to reanalyze all ObjC methods as top level to report Retain
535   //   Count naming convention errors more aggressively.
536   if (isa<ObjCMethodDecl>(D))
537     return false;
538   // We also want to reanalyze all C++ copy and move assignment operators to
539   // separately check the two cases where 'this' aliases with the parameter and
540   // where it may not. (cplusplus.SelfAssignmentChecker)
541   if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
542     if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())
543       return false;
544   }
545 
546   // Otherwise, if we visited the function before, do not reanalyze it.
547   return Visited.count(D);
548 }
549 
550 ExprEngine::InliningModes
551 AnalysisConsumer::getInliningModeForFunction(const Decl *D,
552                                              const SetOfConstDecls &Visited) {
553   // We want to reanalyze all ObjC methods as top level to report Retain
554   // Count naming convention errors more aggressively. But we should tune down
555   // inlining when reanalyzing an already inlined function.
556   if (Visited.count(D) && isa<ObjCMethodDecl>(D)) {
557     const ObjCMethodDecl *ObjCM = cast<ObjCMethodDecl>(D);
558     if (ObjCM->getMethodFamily() != OMF_init)
559       return ExprEngine::Inline_Minimal;
560   }
561 
562   return ExprEngine::Inline_Regular;
563 }
564 
565 void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) {
566   // Build the Call Graph by adding all the top level declarations to the graph.
567   // Note: CallGraph can trigger deserialization of more items from a pch
568   // (though HandleInterestingDecl); triggering additions to LocalTUDecls.
569   // We rely on random access to add the initially processed Decls to CG.
570   CallGraph CG;
571   for (unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) {
572     CG.addToCallGraph(LocalTUDecls[i]);
573   }
574 
575   // Walk over all of the call graph nodes in topological order, so that we
576   // analyze parents before the children. Skip the functions inlined into
577   // the previously processed functions. Use external Visited set to identify
578   // inlined functions. The topological order allows the "do not reanalyze
579   // previously inlined function" performance heuristic to be triggered more
580   // often.
581   SetOfConstDecls Visited;
582   SetOfConstDecls VisitedAsTopLevel;
583   llvm::ReversePostOrderTraversal<clang::CallGraph*> RPOT(&CG);
584   for (llvm::ReversePostOrderTraversal<clang::CallGraph*>::rpo_iterator
585          I = RPOT.begin(), E = RPOT.end(); I != E; ++I) {
586     NumFunctionTopLevel++;
587 
588     CallGraphNode *N = *I;
589     Decl *D = N->getDecl();
590 
591     // Skip the abstract root node.
592     if (!D)
593       continue;
594 
595     // Skip the functions which have been processed already or previously
596     // inlined.
597     if (shouldSkipFunction(D, Visited, VisitedAsTopLevel))
598       continue;
599 
600     // Analyze the function.
601     SetOfConstDecls VisitedCallees;
602 
603     HandleCode(D, AM_Path, getInliningModeForFunction(D, Visited),
604                (Mgr->options.InliningMode == All ? nullptr : &VisitedCallees));
605 
606     // Add the visited callees to the global visited set.
607     for (const Decl *Callee : VisitedCallees)
608       // Decls from CallGraph are already canonical. But Decls coming from
609       // CallExprs may be not. We should canonicalize them manually.
610       Visited.insert(isa<ObjCMethodDecl>(Callee) ? Callee
611                                                  : Callee->getCanonicalDecl());
612     VisitedAsTopLevel.insert(D);
613   }
614 }
615 
616 static bool isBisonFile(ASTContext &C) {
617   const SourceManager &SM = C.getSourceManager();
618   FileID FID = SM.getMainFileID();
619   StringRef Buffer = SM.getBuffer(FID)->getBuffer();
620   if (Buffer.startswith("/* A Bison parser, made by"))
621     return true;
622   return false;
623 }
624 
625 void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) {
626   BugReporter BR(*Mgr);
627   TranslationUnitDecl *TU = C.getTranslationUnitDecl();
628   if (SyntaxCheckTimer)
629     SyntaxCheckTimer->startTimer();
630   checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR);
631   if (SyntaxCheckTimer)
632     SyntaxCheckTimer->stopTimer();
633 
634   // Run the AST-only checks using the order in which functions are defined.
635   // If inlining is not turned on, use the simplest function order for path
636   // sensitive analyzes as well.
637   RecVisitorMode = AM_Syntax;
638   if (!Mgr->shouldInlineCall())
639     RecVisitorMode |= AM_Path;
640   RecVisitorBR = &BR;
641 
642   // Process all the top level declarations.
643   //
644   // Note: TraverseDecl may modify LocalTUDecls, but only by appending more
645   // entries.  Thus we don't use an iterator, but rely on LocalTUDecls
646   // random access.  By doing so, we automatically compensate for iterators
647   // possibly being invalidated, although this is a bit slower.
648   const unsigned LocalTUDeclsSize = LocalTUDecls.size();
649   for (unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) {
650     TraverseDecl(LocalTUDecls[i]);
651   }
652 
653   if (Mgr->shouldInlineCall())
654     HandleDeclsCallGraph(LocalTUDeclsSize);
655 
656   // After all decls handled, run checkers on the entire TranslationUnit.
657   checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR);
658 
659   BR.FlushReports();
660   RecVisitorBR = nullptr;
661 }
662 
663 void AnalysisConsumer::reportAnalyzerProgress(StringRef S) {
664   if (Opts->AnalyzerDisplayProgress)
665     llvm::errs() << S;
666 }
667 
668 void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
669 
670   // Don't run the actions if an error has occurred with parsing the file.
671   DiagnosticsEngine &Diags = PP.getDiagnostics();
672   if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
673     return;
674 
675   if (isBisonFile(C)) {
676     reportAnalyzerProgress("Skipping bison-generated file\n");
677   } else if (Opts->DisableAllCheckers) {
678 
679     // Don't analyze if the user explicitly asked for no checks to be performed
680     // on this file.
681     reportAnalyzerProgress("All checks are disabled using a supplied option\n");
682   } else {
683     // Otherwise, just run the analysis.
684     runAnalysisOnTranslationUnit(C);
685   }
686 
687   // Count how many basic blocks we have not covered.
688   NumBlocksInAnalyzedFunctions = FunctionSummaries.getTotalNumBasicBlocks();
689   NumVisitedBlocksInAnalyzedFunctions =
690       FunctionSummaries.getTotalNumVisitedBasicBlocks();
691   if (NumBlocksInAnalyzedFunctions > 0)
692     PercentReachableBlocks =
693       (FunctionSummaries.getTotalNumVisitedBasicBlocks() * 100) /
694         NumBlocksInAnalyzedFunctions;
695 
696   // Explicitly destroy the PathDiagnosticConsumer.  This will flush its output.
697   // FIXME: This should be replaced with something that doesn't rely on
698   // side-effects in PathDiagnosticConsumer's destructor. This is required when
699   // used with option -disable-free.
700   Mgr.reset();
701 }
702 
703 std::string AnalysisConsumer::getFunctionName(const Decl *D) {
704   std::string Str;
705   llvm::raw_string_ostream OS(Str);
706 
707   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
708     OS << FD->getQualifiedNameAsString();
709 
710     // In C++, there are overloads.
711     if (Ctx->getLangOpts().CPlusPlus) {
712       OS << '(';
713       for (const auto &P : FD->parameters()) {
714         if (P != *FD->param_begin())
715           OS << ", ";
716         OS << P->getType().getAsString();
717       }
718       OS << ')';
719     }
720 
721   } else if (isa<BlockDecl>(D)) {
722     PresumedLoc Loc = Ctx->getSourceManager().getPresumedLoc(D->getLocation());
723 
724     if (Loc.isValid()) {
725       OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
726          << ')';
727     }
728 
729   } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
730 
731     // FIXME: copy-pasted from CGDebugInfo.cpp.
732     OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
733     const DeclContext *DC = OMD->getDeclContext();
734     if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
735       OS << OID->getName();
736     } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
737       OS << OID->getName();
738     } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
739       if (OC->IsClassExtension()) {
740         OS << OC->getClassInterface()->getName();
741       } else {
742         OS << OC->getIdentifier()->getNameStart() << '('
743            << OC->getIdentifier()->getNameStart() << ')';
744       }
745     } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
746       OS << OCD->getClassInterface()->getName() << '('
747          << OCD->getName() << ')';
748     }
749     OS << ' ' << OMD->getSelector().getAsString() << ']';
750 
751   }
752 
753   return OS.str();
754 }
755 
756 AnalysisConsumer::AnalysisMode
757 AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) {
758   if (!Opts->AnalyzeSpecificFunction.empty() &&
759       getFunctionName(D) != Opts->AnalyzeSpecificFunction)
760     return AM_None;
761 
762   // Unless -analyze-all is specified, treat decls differently depending on
763   // where they came from:
764   // - Main source file: run both path-sensitive and non-path-sensitive checks.
765   // - Header files: run non-path-sensitive checks only.
766   // - System headers: don't run any checks.
767   SourceManager &SM = Ctx->getSourceManager();
768   const Stmt *Body = D->getBody();
769   SourceLocation SL = Body ? Body->getBeginLoc() : D->getLocation();
770   SL = SM.getExpansionLoc(SL);
771 
772   if (!Opts->AnalyzeAll && !Mgr->isInCodeFile(SL)) {
773     if (SL.isInvalid() || SM.isInSystemHeader(SL))
774       return AM_None;
775     return Mode & ~AM_Path;
776   }
777 
778   return Mode;
779 }
780 
781 void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
782                                   ExprEngine::InliningModes IMode,
783                                   SetOfConstDecls *VisitedCallees) {
784   if (!D->hasBody())
785     return;
786   Mode = getModeForDecl(D, Mode);
787   if (Mode == AM_None)
788     return;
789 
790   // Clear the AnalysisManager of old AnalysisDeclContexts.
791   Mgr->ClearContexts();
792   // Ignore autosynthesized code.
793   if (Mgr->getAnalysisDeclContext(D)->isBodyAutosynthesized())
794     return;
795 
796   DisplayFunction(D, Mode, IMode);
797   CFG *DeclCFG = Mgr->getCFG(D);
798   if (DeclCFG)
799     MaxCFGSize.updateMax(DeclCFG->size());
800 
801   BugReporter BR(*Mgr);
802 
803   if (Mode & AM_Syntax) {
804     if (SyntaxCheckTimer)
805       SyntaxCheckTimer->startTimer();
806     checkerMgr->runCheckersOnASTBody(D, *Mgr, BR);
807     if (SyntaxCheckTimer)
808       SyntaxCheckTimer->stopTimer();
809   }
810 
811   BR.FlushReports();
812 
813   if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) {
814     RunPathSensitiveChecks(D, IMode, VisitedCallees);
815     if (IMode != ExprEngine::Inline_Minimal)
816       NumFunctionsAnalyzed++;
817   }
818 }
819 
820 //===----------------------------------------------------------------------===//
821 // Path-sensitive checking.
822 //===----------------------------------------------------------------------===//
823 
824 void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
825                                               ExprEngine::InliningModes IMode,
826                                               SetOfConstDecls *VisitedCallees) {
827   // Construct the analysis engine.  First check if the CFG is valid.
828   // FIXME: Inter-procedural analysis will need to handle invalid CFGs.
829   if (!Mgr->getCFG(D))
830     return;
831 
832   // See if the LiveVariables analysis scales.
833   if (!Mgr->getAnalysisDeclContext(D)->getAnalysis<RelaxedLiveVariables>())
834     return;
835 
836   ExprEngine Eng(CTU, *Mgr, VisitedCallees, &FunctionSummaries, IMode);
837 
838   // Execute the worklist algorithm.
839   if (ExprEngineTimer)
840     ExprEngineTimer->startTimer();
841   Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
842                       Mgr->options.MaxNodesPerTopLevelFunction);
843   if (ExprEngineTimer)
844     ExprEngineTimer->stopTimer();
845 
846   if (!Mgr->options.DumpExplodedGraphTo.empty())
847     Eng.DumpGraph(Mgr->options.TrimGraph, Mgr->options.DumpExplodedGraphTo);
848 
849   // Visualize the exploded graph.
850   if (Mgr->options.visualizeExplodedGraphWithGraphViz)
851     Eng.ViewGraph(Mgr->options.TrimGraph);
852 
853   // Display warnings.
854   if (BugReporterTimer)
855     BugReporterTimer->startTimer();
856   Eng.getBugReporter().FlushReports();
857   if (BugReporterTimer)
858     BugReporterTimer->stopTimer();
859 }
860 
861 //===----------------------------------------------------------------------===//
862 // AnalysisConsumer creation.
863 //===----------------------------------------------------------------------===//
864 
865 std::unique_ptr<AnalysisASTConsumer>
866 ento::CreateAnalysisConsumer(CompilerInstance &CI) {
867   // Disable the effects of '-Werror' when using the AnalysisConsumer.
868   CI.getPreprocessor().getDiagnostics().setWarningsAsErrors(false);
869 
870   AnalyzerOptionsRef analyzerOpts = CI.getAnalyzerOpts();
871   bool hasModelPath = analyzerOpts->Config.count("model-path") > 0;
872 
873   return std::make_unique<AnalysisConsumer>(
874       CI, CI.getFrontendOpts().OutputFile, analyzerOpts,
875       CI.getFrontendOpts().Plugins,
876       hasModelPath ? new ModelInjector(CI) : nullptr);
877 }
878