clang  7.0.0svn
AnalysisConsumer.cpp
Go to the documentation of this file.
1 //===--- AnalysisConsumer.cpp - ASTConsumer for running Analyses ----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // "Meta" ASTConsumer for running different source analyses.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "ModelInjector.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
21 #include "clang/Analysis/CFG.h"
27 #include "clang/Lex/Preprocessor.h"
37 #include "llvm/ADT/PostOrderIterator.h"
38 #include "llvm/ADT/Statistic.h"
39 #include "llvm/Support/FileSystem.h"
40 #include "llvm/Support/Path.h"
41 #include "llvm/Support/Program.h"
42 #include "llvm/Support/Timer.h"
43 #include "llvm/Support/raw_ostream.h"
44 #include <memory>
45 #include <queue>
46 #include <utility>
47 
48 using namespace clang;
49 using namespace ento;
50 
51 #define DEBUG_TYPE "AnalysisConsumer"
52 
53 static std::unique_ptr<ExplodedNode::Auditor> CreateUbiViz();
54 
55 STATISTIC(NumFunctionTopLevel, "The # of functions at top level.");
56 STATISTIC(NumFunctionsAnalyzed,
57  "The # of functions and blocks analyzed (as top level "
58  "with inlining turned on).");
59 STATISTIC(NumBlocksInAnalyzedFunctions,
60  "The # of basic blocks in the analyzed functions.");
61 STATISTIC(NumVisitedBlocksInAnalyzedFunctions,
62  "The # of visited basic blocks in the analyzed functions.");
63 STATISTIC(PercentReachableBlocks, "The % of reachable basic blocks.");
64 STATISTIC(MaxCFGSize, "The maximum number of basic blocks in a function.");
65 
66 //===----------------------------------------------------------------------===//
67 // Special PathDiagnosticConsumers.
68 //===----------------------------------------------------------------------===//
69 
70 void ento::createPlistHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
72  const std::string &prefix,
73  const Preprocessor &PP) {
74  createHTMLDiagnosticConsumer(AnalyzerOpts, C,
75  llvm::sys::path::parent_path(prefix), PP);
76  createPlistMultiFileDiagnosticConsumer(AnalyzerOpts, C, prefix, PP);
77 }
78 
79 void ento::createTextPathDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
81  const std::string &Prefix,
82  const clang::Preprocessor &PP) {
83  llvm_unreachable("'text' consumer should be enabled on ClangDiags");
84 }
85 
86 namespace {
87 class ClangDiagPathDiagConsumer : public PathDiagnosticConsumer {
89  bool IncludePath;
90 public:
91  ClangDiagPathDiagConsumer(DiagnosticsEngine &Diag)
92  : Diag(Diag), IncludePath(false) {}
93  ~ClangDiagPathDiagConsumer() override {}
94  StringRef getName() const override { return "ClangDiags"; }
95 
96  bool supportsLogicalOpControlFlow() const override { return true; }
97  bool supportsCrossFileDiagnostics() const override { return true; }
98 
99  PathGenerationScheme getGenerationScheme() const override {
100  return IncludePath ? Minimal : None;
101  }
102 
103  void enablePaths() {
104  IncludePath = true;
105  }
106 
107  void FlushDiagnosticsImpl(std::vector<const PathDiagnostic *> &Diags,
108  FilesMade *filesMade) override {
109  unsigned WarnID = Diag.getCustomDiagID(DiagnosticsEngine::Warning, "%0");
110  unsigned NoteID = Diag.getCustomDiagID(DiagnosticsEngine::Note, "%0");
111 
112  for (std::vector<const PathDiagnostic*>::iterator I = Diags.begin(),
113  E = Diags.end(); I != E; ++I) {
114  const PathDiagnostic *PD = *I;
115  SourceLocation WarnLoc = PD->getLocation().asLocation();
116  Diag.Report(WarnLoc, WarnID) << PD->getShortDescription()
117  << PD->path.back()->getRanges();
118 
119  // First, add extra notes, even if paths should not be included.
120  for (const auto &Piece : PD->path) {
121  if (!isa<PathDiagnosticNotePiece>(Piece.get()))
122  continue;
123 
124  SourceLocation NoteLoc = Piece->getLocation().asLocation();
125  Diag.Report(NoteLoc, NoteID) << Piece->getString()
126  << Piece->getRanges();
127  }
128 
129  if (!IncludePath)
130  continue;
131 
132  // Then, add the path notes if necessary.
133  PathPieces FlatPath = PD->path.flatten(/*ShouldFlattenMacros=*/true);
134  for (const auto &Piece : FlatPath) {
135  if (isa<PathDiagnosticNotePiece>(Piece.get()))
136  continue;
137 
138  SourceLocation NoteLoc = Piece->getLocation().asLocation();
139  Diag.Report(NoteLoc, NoteID) << Piece->getString()
140  << Piece->getRanges();
141  }
142  }
143  }
144 };
145 } // end anonymous namespace
146 
147 //===----------------------------------------------------------------------===//
148 // AnalysisConsumer declaration.
149 //===----------------------------------------------------------------------===//
150 
151 namespace {
152 
153 class AnalysisConsumer : public AnalysisASTConsumer,
154  public RecursiveASTVisitor<AnalysisConsumer> {
155  enum {
156  AM_None = 0,
157  AM_Syntax = 0x1,
158  AM_Path = 0x2
159  };
160  typedef unsigned AnalysisMode;
161 
162  /// Mode of the analyzes while recursively visiting Decls.
163  AnalysisMode RecVisitorMode;
164  /// Bug Reporter to use while recursively visiting Decls.
165  BugReporter *RecVisitorBR;
166 
167  std::vector<std::function<void(CheckerRegistry &)>> CheckerRegistrationFns;
168 
169 public:
170  ASTContext *Ctx;
171  const Preprocessor &PP;
172  const std::string OutDir;
173  AnalyzerOptionsRef Opts;
174  ArrayRef<std::string> Plugins;
175  CodeInjector *Injector;
177 
178  /// Stores the declarations from the local translation unit.
179  /// Note, we pre-compute the local declarations at parse time as an
180  /// optimization to make sure we do not deserialize everything from disk.
181  /// The local declaration to all declarations ratio might be very small when
182  /// working with a PCH file.
183  SetOfDecls LocalTUDecls;
184 
185  // Set of PathDiagnosticConsumers. Owned by AnalysisManager.
186  PathDiagnosticConsumers PathConsumers;
187 
188  StoreManagerCreator CreateStoreMgr;
189  ConstraintManagerCreator CreateConstraintMgr;
190 
191  std::unique_ptr<CheckerManager> checkerMgr;
192  std::unique_ptr<AnalysisManager> Mgr;
193 
194  /// Time the analyzes time of each translation unit.
195  std::unique_ptr<llvm::TimerGroup> AnalyzerTimers;
196  std::unique_ptr<llvm::Timer> TUTotalTimer;
197 
198  /// The information about analyzed functions shared throughout the
199  /// translation unit.
200  FunctionSummariesTy FunctionSummaries;
201 
202  AnalysisConsumer(CompilerInstance &CI, const std::string &outdir,
204  CodeInjector *injector)
205  : RecVisitorMode(0), RecVisitorBR(nullptr), Ctx(nullptr),
206  PP(CI.getPreprocessor()), OutDir(outdir), Opts(std::move(opts)),
207  Plugins(plugins), Injector(injector), CTU(CI) {
208  DigestAnalyzerOptions();
209  if (Opts->PrintStats || Opts->shouldSerializeStats()) {
210  AnalyzerTimers = llvm::make_unique<llvm::TimerGroup>(
211  "analyzer", "Analyzer timers");
212  TUTotalTimer = llvm::make_unique<llvm::Timer>(
213  "time", "Analyzer total time", *AnalyzerTimers);
214  llvm::EnableStatistics(/* PrintOnExit= */ false);
215  }
216  }
217 
218  ~AnalysisConsumer() override {
219  if (Opts->PrintStats) {
220  llvm::PrintStatistics();
221  }
222  }
223 
224  void DigestAnalyzerOptions() {
225  if (Opts->AnalysisDiagOpt != PD_NONE) {
226  // Create the PathDiagnosticConsumer.
227  ClangDiagPathDiagConsumer *clangDiags =
228  new ClangDiagPathDiagConsumer(PP.getDiagnostics());
229  PathConsumers.push_back(clangDiags);
230 
231  if (Opts->AnalysisDiagOpt == PD_TEXT) {
232  clangDiags->enablePaths();
233 
234  } else if (!OutDir.empty()) {
235  switch (Opts->AnalysisDiagOpt) {
236  default:
237 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \
238  case PD_##NAME: \
239  CREATEFN(*Opts.get(), PathConsumers, OutDir, PP); \
240  break;
241 #include "clang/StaticAnalyzer/Core/Analyses.def"
242  }
243  }
244  }
245 
246  // Create the analyzer component creators.
247  switch (Opts->AnalysisStoreOpt) {
248  default:
249  llvm_unreachable("Unknown store manager.");
250 #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATEFN) \
251  case NAME##Model: CreateStoreMgr = CREATEFN; break;
252 #include "clang/StaticAnalyzer/Core/Analyses.def"
253  }
254 
255  switch (Opts->AnalysisConstraintsOpt) {
256  default:
257  llvm_unreachable("Unknown constraint manager.");
258 #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATEFN) \
259  case NAME##Model: CreateConstraintMgr = CREATEFN; break;
260 #include "clang/StaticAnalyzer/Core/Analyses.def"
261  }
262  }
263 
264  void DisplayFunction(const Decl *D, AnalysisMode Mode,
266  if (!Opts->AnalyzerDisplayProgress)
267  return;
268 
269  SourceManager &SM = Mgr->getASTContext().getSourceManager();
271  if (Loc.isValid()) {
272  llvm::errs() << "ANALYZE";
273 
274  if (Mode == AM_Syntax)
275  llvm::errs() << " (Syntax)";
276  else if (Mode == AM_Path) {
277  llvm::errs() << " (Path, ";
278  switch (IMode) {
280  llvm::errs() << " Inline_Minimal";
281  break;
283  llvm::errs() << " Inline_Regular";
284  break;
285  }
286  llvm::errs() << ")";
287  }
288  else
289  assert(Mode == (AM_Syntax | AM_Path) && "Unexpected mode!");
290 
291  llvm::errs() << ": " << Loc.getFilename() << ' '
292  << getFunctionName(D) << '\n';
293  }
294  }
295 
296  void Initialize(ASTContext &Context) override {
297  Ctx = &Context;
298  checkerMgr =
299  createCheckerManager(*Opts, PP.getLangOpts(), Plugins,
300  CheckerRegistrationFns, PP.getDiagnostics());
301 
302  Mgr = llvm::make_unique<AnalysisManager>(
303  *Ctx, PP.getDiagnostics(), PP.getLangOpts(), PathConsumers,
304  CreateStoreMgr, CreateConstraintMgr, checkerMgr.get(), *Opts, Injector);
305  }
306 
307  /// Store the top level decls in the set to be processed later on.
308  /// (Doing this pre-processing avoids deserialization of data from PCH.)
309  bool HandleTopLevelDecl(DeclGroupRef D) override;
310  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override;
311 
312  void HandleTranslationUnit(ASTContext &C) override;
313 
314  /// Determine which inlining mode should be used when this function is
315  /// analyzed. This allows to redefine the default inlining policies when
316  /// analyzing a given function.
318  getInliningModeForFunction(const Decl *D, const SetOfConstDecls &Visited);
319 
320  /// Build the call graph for all the top level decls of this TU and
321  /// use it to define the order in which the functions should be visited.
322  void HandleDeclsCallGraph(const unsigned LocalTUDeclsSize);
323 
324  /// Run analyzes(syntax or path sensitive) on the given function.
325  /// \param Mode - determines if we are requesting syntax only or path
326  /// sensitive only analysis.
327  /// \param VisitedCallees - The output parameter, which is populated with the
328  /// set of functions which should be considered analyzed after analyzing the
329  /// given root function.
330  void HandleCode(Decl *D, AnalysisMode Mode,
332  SetOfConstDecls *VisitedCallees = nullptr);
333 
334  void RunPathSensitiveChecks(Decl *D,
336  SetOfConstDecls *VisitedCallees);
337  void ActionExprEngine(Decl *D, bool ObjCGCEnabled,
339  SetOfConstDecls *VisitedCallees);
340 
341  /// Visitors for the RecursiveASTVisitor.
342  bool shouldWalkTypesOfTypeLocs() const { return false; }
343 
344  /// Handle callbacks for arbitrary Decls.
345  bool VisitDecl(Decl *D) {
346  AnalysisMode Mode = getModeForDecl(D, RecVisitorMode);
347  if (Mode & AM_Syntax)
348  checkerMgr->runCheckersOnASTDecl(D, *Mgr, *RecVisitorBR);
349  return true;
350  }
351 
352  bool VisitFunctionDecl(FunctionDecl *FD) {
353  IdentifierInfo *II = FD->getIdentifier();
354  if (II && II->getName().startswith("__inline"))
355  return true;
356 
357  // We skip function template definitions, as their semantics is
358  // only determined when they are instantiated.
359  if (FD->isThisDeclarationADefinition() &&
360  !FD->isDependentContext()) {
361  assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
362  HandleCode(FD, RecVisitorMode);
363  }
364  return true;
365  }
366 
367  bool VisitObjCMethodDecl(ObjCMethodDecl *MD) {
368  if (MD->isThisDeclarationADefinition()) {
369  assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
370  HandleCode(MD, RecVisitorMode);
371  }
372  return true;
373  }
374 
375  bool VisitBlockDecl(BlockDecl *BD) {
376  if (BD->hasBody()) {
377  assert(RecVisitorMode == AM_Syntax || Mgr->shouldInlineCall() == false);
378  // Since we skip function template definitions, we should skip blocks
379  // declared in those functions as well.
380  if (!BD->isDependentContext()) {
381  HandleCode(BD, RecVisitorMode);
382  }
383  }
384  return true;
385  }
386 
387  void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) override {
388  PathConsumers.push_back(Consumer);
389  }
390 
391  void AddCheckerRegistrationFn(std::function<void(CheckerRegistry&)> Fn) override {
392  CheckerRegistrationFns.push_back(std::move(Fn));
393  }
394 
395 private:
396  void storeTopLevelDecls(DeclGroupRef DG);
397  std::string getFunctionName(const Decl *D);
398 
399  /// Check if we should skip (not analyze) the given function.
400  AnalysisMode getModeForDecl(Decl *D, AnalysisMode Mode);
401  void runAnalysisOnTranslationUnit(ASTContext &C);
402 
403  /// Print \p S to stderr if \c Opts->AnalyzerDisplayProgress is set.
404  void reportAnalyzerProgress(StringRef S);
405 };
406 } // end anonymous namespace
407 
408 
409 //===----------------------------------------------------------------------===//
410 // AnalysisConsumer implementation.
411 //===----------------------------------------------------------------------===//
412 bool AnalysisConsumer::HandleTopLevelDecl(DeclGroupRef DG) {
413  storeTopLevelDecls(DG);
414  return true;
415 }
416 
417 void AnalysisConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) {
418  storeTopLevelDecls(DG);
419 }
420 
421 void AnalysisConsumer::storeTopLevelDecls(DeclGroupRef DG) {
422  for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) {
423 
424  // Skip ObjCMethodDecl, wait for the objc container to avoid
425  // analyzing twice.
426  if (isa<ObjCMethodDecl>(*I))
427  continue;
428 
429  LocalTUDecls.push_back(*I);
430  }
431 }
432 
433 static bool shouldSkipFunction(const Decl *D,
434  const SetOfConstDecls &Visited,
435  const SetOfConstDecls &VisitedAsTopLevel) {
436  if (VisitedAsTopLevel.count(D))
437  return true;
438 
439  // We want to re-analyse the functions as top level in the following cases:
440  // - The 'init' methods should be reanalyzed because
441  // ObjCNonNilReturnValueChecker assumes that '[super init]' never returns
442  // 'nil' and unless we analyze the 'init' functions as top level, we will
443  // not catch errors within defensive code.
444  // - We want to reanalyze all ObjC methods as top level to report Retain
445  // Count naming convention errors more aggressively.
446  if (isa<ObjCMethodDecl>(D))
447  return false;
448  // We also want to reanalyze all C++ copy and move assignment operators to
449  // separately check the two cases where 'this' aliases with the parameter and
450  // where it may not. (cplusplus.SelfAssignmentChecker)
451  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
452  if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())
453  return false;
454  }
455 
456  // Otherwise, if we visited the function before, do not reanalyze it.
457  return Visited.count(D);
458 }
459 
461 AnalysisConsumer::getInliningModeForFunction(const Decl *D,
462  const SetOfConstDecls &Visited) {
463  // We want to reanalyze all ObjC methods as top level to report Retain
464  // Count naming convention errors more aggressively. But we should tune down
465  // inlining when reanalyzing an already inlined function.
466  if (Visited.count(D) && isa<ObjCMethodDecl>(D)) {
467  const ObjCMethodDecl *ObjCM = cast<ObjCMethodDecl>(D);
468  if (ObjCM->getMethodFamily() != OMF_init)
470  }
471 
473 }
474 
475 void AnalysisConsumer::HandleDeclsCallGraph(const unsigned LocalTUDeclsSize) {
476  // Build the Call Graph by adding all the top level declarations to the graph.
477  // Note: CallGraph can trigger deserialization of more items from a pch
478  // (though HandleInterestingDecl); triggering additions to LocalTUDecls.
479  // We rely on random access to add the initially processed Decls to CG.
480  CallGraph CG;
481  for (unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) {
482  CG.addToCallGraph(LocalTUDecls[i]);
483  }
484 
485  // Walk over all of the call graph nodes in topological order, so that we
486  // analyze parents before the children. Skip the functions inlined into
487  // the previously processed functions. Use external Visited set to identify
488  // inlined functions. The topological order allows the "do not reanalyze
489  // previously inlined function" performance heuristic to be triggered more
490  // often.
491  SetOfConstDecls Visited;
492  SetOfConstDecls VisitedAsTopLevel;
493  llvm::ReversePostOrderTraversal<clang::CallGraph*> RPOT(&CG);
494  for (llvm::ReversePostOrderTraversal<clang::CallGraph*>::rpo_iterator
495  I = RPOT.begin(), E = RPOT.end(); I != E; ++I) {
496  NumFunctionTopLevel++;
497 
498  CallGraphNode *N = *I;
499  Decl *D = N->getDecl();
500 
501  // Skip the abstract root node.
502  if (!D)
503  continue;
504 
505  // Skip the functions which have been processed already or previously
506  // inlined.
507  if (shouldSkipFunction(D, Visited, VisitedAsTopLevel))
508  continue;
509 
510  // Analyze the function.
511  SetOfConstDecls VisitedCallees;
512 
513  HandleCode(D, AM_Path, getInliningModeForFunction(D, Visited),
514  (Mgr->options.InliningMode == All ? nullptr : &VisitedCallees));
515 
516  // Add the visited callees to the global visited set.
517  for (const Decl *Callee : VisitedCallees)
518  // Decls from CallGraph are already canonical. But Decls coming from
519  // CallExprs may be not. We should canonicalize them manually.
520  Visited.insert(isa<ObjCMethodDecl>(Callee) ? Callee
521  : Callee->getCanonicalDecl());
522  VisitedAsTopLevel.insert(D);
523  }
524 }
525 
526 static bool isBisonFile(ASTContext &C) {
527  const SourceManager &SM = C.getSourceManager();
528  FileID FID = SM.getMainFileID();
529  StringRef Buffer = SM.getBuffer(FID)->getBuffer();
530  if (Buffer.startswith("/* A Bison parser, made by"))
531  return true;
532  return false;
533 }
534 
535 void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) {
536  BugReporter BR(*Mgr);
538  checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR);
539 
540  // Run the AST-only checks using the order in which functions are defined.
541  // If inlining is not turned on, use the simplest function order for path
542  // sensitive analyzes as well.
543  RecVisitorMode = AM_Syntax;
544  if (!Mgr->shouldInlineCall())
545  RecVisitorMode |= AM_Path;
546  RecVisitorBR = &BR;
547 
548  // Process all the top level declarations.
549  //
550  // Note: TraverseDecl may modify LocalTUDecls, but only by appending more
551  // entries. Thus we don't use an iterator, but rely on LocalTUDecls
552  // random access. By doing so, we automatically compensate for iterators
553  // possibly being invalidated, although this is a bit slower.
554  const unsigned LocalTUDeclsSize = LocalTUDecls.size();
555  for (unsigned i = 0 ; i < LocalTUDeclsSize ; ++i) {
556  TraverseDecl(LocalTUDecls[i]);
557  }
558 
559  if (Mgr->shouldInlineCall())
560  HandleDeclsCallGraph(LocalTUDeclsSize);
561 
562  // After all decls handled, run checkers on the entire TranslationUnit.
563  checkerMgr->runCheckersOnEndOfTranslationUnit(TU, *Mgr, BR);
564 
565  RecVisitorBR = nullptr;
566 }
567 
568 void AnalysisConsumer::reportAnalyzerProgress(StringRef S) {
569  if (Opts->AnalyzerDisplayProgress)
570  llvm::errs() << S;
571 }
572 
573 void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
574 
575  // Don't run the actions if an error has occurred with parsing the file.
576  DiagnosticsEngine &Diags = PP.getDiagnostics();
577  if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
578  return;
579 
580  if (TUTotalTimer) TUTotalTimer->startTimer();
581 
582  if (isBisonFile(C)) {
583  reportAnalyzerProgress("Skipping bison-generated file\n");
584  } else if (Opts->DisableAllChecks) {
585 
586  // Don't analyze if the user explicitly asked for no checks to be performed
587  // on this file.
588  reportAnalyzerProgress("All checks are disabled using a supplied option\n");
589  } else {
590  // Otherwise, just run the analysis.
591  runAnalysisOnTranslationUnit(C);
592  }
593 
594  if (TUTotalTimer) TUTotalTimer->stopTimer();
595 
596  // Count how many basic blocks we have not covered.
597  NumBlocksInAnalyzedFunctions = FunctionSummaries.getTotalNumBasicBlocks();
598  NumVisitedBlocksInAnalyzedFunctions =
599  FunctionSummaries.getTotalNumVisitedBasicBlocks();
600  if (NumBlocksInAnalyzedFunctions > 0)
601  PercentReachableBlocks =
602  (FunctionSummaries.getTotalNumVisitedBasicBlocks() * 100) /
603  NumBlocksInAnalyzedFunctions;
604 
605  // Explicitly destroy the PathDiagnosticConsumer. This will flush its output.
606  // FIXME: This should be replaced with something that doesn't rely on
607  // side-effects in PathDiagnosticConsumer's destructor. This is required when
608  // used with option -disable-free.
609  Mgr.reset();
610 }
611 
612 std::string AnalysisConsumer::getFunctionName(const Decl *D) {
613  std::string Str;
614  llvm::raw_string_ostream OS(Str);
615 
616  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
617  OS << FD->getQualifiedNameAsString();
618 
619  // In C++, there are overloads.
620  if (Ctx->getLangOpts().CPlusPlus) {
621  OS << '(';
622  for (const auto &P : FD->parameters()) {
623  if (P != *FD->param_begin())
624  OS << ", ";
625  OS << P->getType().getAsString();
626  }
627  OS << ')';
628  }
629 
630  } else if (isa<BlockDecl>(D)) {
631  PresumedLoc Loc = Ctx->getSourceManager().getPresumedLoc(D->getLocation());
632 
633  if (Loc.isValid()) {
634  OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
635  << ')';
636  }
637 
638  } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
639 
640  // FIXME: copy-pasted from CGDebugInfo.cpp.
641  OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
642  const DeclContext *DC = OMD->getDeclContext();
643  if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
644  OS << OID->getName();
645  } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
646  OS << OID->getName();
647  } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
648  if (OC->IsClassExtension()) {
649  OS << OC->getClassInterface()->getName();
650  } else {
651  OS << OC->getIdentifier()->getNameStart() << '('
652  << OC->getIdentifier()->getNameStart() << ')';
653  }
654  } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
655  OS << OCD->getClassInterface()->getName() << '('
656  << OCD->getName() << ')';
657  } else if (isa<ObjCProtocolDecl>(DC)) {
658  // We can extract the type of the class from the self pointer.
659  if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
660  QualType ClassTy =
661  cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType();
662  ClassTy.print(OS, PrintingPolicy(LangOptions()));
663  }
664  }
665  OS << ' ' << OMD->getSelector().getAsString() << ']';
666 
667  }
668 
669  return OS.str();
670 }
671 
672 AnalysisConsumer::AnalysisMode
673 AnalysisConsumer::getModeForDecl(Decl *D, AnalysisMode Mode) {
674  if (!Opts->AnalyzeSpecificFunction.empty() &&
675  getFunctionName(D) != Opts->AnalyzeSpecificFunction)
676  return AM_None;
677 
678  // Unless -analyze-all is specified, treat decls differently depending on
679  // where they came from:
680  // - Main source file: run both path-sensitive and non-path-sensitive checks.
681  // - Header files: run non-path-sensitive checks only.
682  // - System headers: don't run any checks.
683  SourceManager &SM = Ctx->getSourceManager();
684  const Stmt *Body = D->getBody();
685  SourceLocation SL = Body ? Body->getLocStart() : D->getLocation();
686  SL = SM.getExpansionLoc(SL);
687 
688  if (!Opts->AnalyzeAll && !Mgr->isInCodeFile(SL)) {
689  if (SL.isInvalid() || SM.isInSystemHeader(SL))
690  return AM_None;
691  return Mode & ~AM_Path;
692  }
693 
694  return Mode;
695 }
696 
697 void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,
699  SetOfConstDecls *VisitedCallees) {
700  if (!D->hasBody())
701  return;
702  Mode = getModeForDecl(D, Mode);
703  if (Mode == AM_None)
704  return;
705 
706  // Clear the AnalysisManager of old AnalysisDeclContexts.
707  Mgr->ClearContexts();
708  // Ignore autosynthesized code.
709  if (Mgr->getAnalysisDeclContext(D)->isBodyAutosynthesized())
710  return;
711 
712  DisplayFunction(D, Mode, IMode);
713  CFG *DeclCFG = Mgr->getCFG(D);
714  if (DeclCFG)
715  MaxCFGSize.updateMax(DeclCFG->size());
716 
717  BugReporter BR(*Mgr);
718 
719  if (Mode & AM_Syntax)
720  checkerMgr->runCheckersOnASTBody(D, *Mgr, BR);
721  if ((Mode & AM_Path) && checkerMgr->hasPathSensitiveCheckers()) {
722  RunPathSensitiveChecks(D, IMode, VisitedCallees);
723  if (IMode != ExprEngine::Inline_Minimal)
724  NumFunctionsAnalyzed++;
725  }
726 }
727 
728 //===----------------------------------------------------------------------===//
729 // Path-sensitive checking.
730 //===----------------------------------------------------------------------===//
731 
732 void AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled,
734  SetOfConstDecls *VisitedCallees) {
735  // Construct the analysis engine. First check if the CFG is valid.
736  // FIXME: Inter-procedural analysis will need to handle invalid CFGs.
737  if (!Mgr->getCFG(D))
738  return;
739 
740  // See if the LiveVariables analysis scales.
741  if (!Mgr->getAnalysisDeclContext(D)->getAnalysis<RelaxedLiveVariables>())
742  return;
743 
744  ExprEngine Eng(CTU, *Mgr, ObjCGCEnabled, VisitedCallees, &FunctionSummaries,
745  IMode);
746 
747  // Set the graph auditor.
748  std::unique_ptr<ExplodedNode::Auditor> Auditor;
749  if (Mgr->options.visualizeExplodedGraphWithUbiGraph) {
750  Auditor = CreateUbiViz();
751  ExplodedNode::SetAuditor(Auditor.get());
752  }
753 
754  // Execute the worklist algorithm.
755  Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
756  Mgr->options.getMaxNodesPerTopLevelFunction());
757 
758  // Release the auditor (if any) so that it doesn't monitor the graph
759  // created BugReporter.
760  ExplodedNode::SetAuditor(nullptr);
761 
762  // Visualize the exploded graph.
763  if (Mgr->options.visualizeExplodedGraphWithGraphViz)
764  Eng.ViewGraph(Mgr->options.TrimGraph);
765 
766  // Display warnings.
768 }
769 
770 void AnalysisConsumer::RunPathSensitiveChecks(Decl *D,
772  SetOfConstDecls *Visited) {
773 
774  switch (Mgr->getLangOpts().getGC()) {
775  case LangOptions::NonGC:
776  ActionExprEngine(D, false, IMode, Visited);
777  break;
778 
779  case LangOptions::GCOnly:
780  ActionExprEngine(D, true, IMode, Visited);
781  break;
782 
784  ActionExprEngine(D, false, IMode, Visited);
785  ActionExprEngine(D, true, IMode, Visited);
786  break;
787  }
788 }
789 
790 //===----------------------------------------------------------------------===//
791 // AnalysisConsumer creation.
792 //===----------------------------------------------------------------------===//
793 
794 std::unique_ptr<AnalysisASTConsumer>
796  // Disable the effects of '-Werror' when using the AnalysisConsumer.
798 
799  AnalyzerOptionsRef analyzerOpts = CI.getAnalyzerOpts();
800  bool hasModelPath = analyzerOpts->Config.count("model-path") > 0;
801 
802  return llvm::make_unique<AnalysisConsumer>(
803  CI, CI.getFrontendOpts().OutputFile, analyzerOpts,
804  CI.getFrontendOpts().Plugins,
805  hasModelPath ? new ModelInjector(CI) : nullptr);
806 }
807 
808 //===----------------------------------------------------------------------===//
809 // Ubigraph Visualization. FIXME: Move to separate file.
810 //===----------------------------------------------------------------------===//
811 
812 namespace {
813 
814 class UbigraphViz : public ExplodedNode::Auditor {
815  std::unique_ptr<raw_ostream> Out;
816  std::string Filename;
817  unsigned Cntr;
818 
819  typedef llvm::DenseMap<void*,unsigned> VMap;
820  VMap M;
821 
822 public:
823  UbigraphViz(std::unique_ptr<raw_ostream> Out, StringRef Filename);
824 
825  ~UbigraphViz() override;
826 
827  void AddEdge(ExplodedNode *Src, ExplodedNode *Dst) override;
828 };
829 
830 } // end anonymous namespace
831 
832 static std::unique_ptr<ExplodedNode::Auditor> CreateUbiViz() {
834  int FD;
835  llvm::sys::fs::createTemporaryFile("llvm_ubi", "", FD, P);
836  llvm::errs() << "Writing '" << P << "'.\n";
837 
838  auto Stream = llvm::make_unique<llvm::raw_fd_ostream>(FD, true);
839 
840  return llvm::make_unique<UbigraphViz>(std::move(Stream), P);
841 }
842 
843 void UbigraphViz::AddEdge(ExplodedNode *Src, ExplodedNode *Dst) {
844 
845  assert (Src != Dst && "Self-edges are not allowed.");
846 
847  // Lookup the Src. If it is a new node, it's a root.
848  VMap::iterator SrcI= M.find(Src);
849  unsigned SrcID;
850 
851  if (SrcI == M.end()) {
852  M[Src] = SrcID = Cntr++;
853  *Out << "('vertex', " << SrcID << ", ('color','#00ff00'))\n";
854  }
855  else
856  SrcID = SrcI->second;
857 
858  // Lookup the Dst.
859  VMap::iterator DstI= M.find(Dst);
860  unsigned DstID;
861 
862  if (DstI == M.end()) {
863  M[Dst] = DstID = Cntr++;
864  *Out << "('vertex', " << DstID << ")\n";
865  }
866  else {
867  // We have hit DstID before. Change its style to reflect a cache hit.
868  DstID = DstI->second;
869  *Out << "('change_vertex_style', " << DstID << ", 1)\n";
870  }
871 
872  // Add the edge.
873  *Out << "('edge', " << SrcID << ", " << DstID
874  << ", ('arrow','true'), ('oriented', 'true'))\n";
875 }
876 
877 UbigraphViz::UbigraphViz(std::unique_ptr<raw_ostream> OutStream,
878  StringRef Filename)
879  : Out(std::move(OutStream)), Filename(Filename), Cntr(0) {
880 
881  *Out << "('vertex_style_attribute', 0, ('shape', 'icosahedron'))\n";
882  *Out << "('vertex_style', 1, 0, ('shape', 'sphere'), ('color', '#ffcc66'),"
883  " ('size', '1.5'))\n";
884 }
885 
886 UbigraphViz::~UbigraphViz() {
887  Out.reset();
888  llvm::errs() << "Running 'ubiviz' program... ";
889  std::string ErrMsg;
890  std::string Ubiviz;
891  if (auto Path = llvm::sys::findProgramByName("ubiviz"))
892  Ubiviz = *Path;
893  std::array<StringRef, 2> Args{{Ubiviz, Filename}};
894 
895  if (llvm::sys::ExecuteAndWait(Ubiviz, Args, llvm::None, {}, 0, 0, &ErrMsg)) {
896  llvm::errs() << "Error viewing graph: " << ErrMsg << "\n";
897  }
898 
899  // Delete the file.
900  llvm::sys::fs::remove(Filename);
901 }
Manages a set of available checkers for running a static analysis.
The AST-based call graph.
Definition: CallGraph.h:42
std::string OutputFile
The output file, if any.
Represents a function declaration or definition.
Definition: Decl.h:1714
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
bool isThisDeclarationADefinition() const
Returns whether this specific method is a definition.
Definition: DeclObjC.h:535
bool hasErrorOccurred() const
Definition: Diagnostic.h:746
A (possibly-)qualified type.
Definition: Type.h:655
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:998
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: DeclBase.h:984
Stmt - This represents one statement.
Definition: Stmt.h:66
unsigned size() const
size - Return the total number of CFGBlocks within the CFG This is simply a renaming of the getNumBlo...
Definition: CFG.h:1174
Defines the SourceManager interface.
iterator end()
Definition: DeclGroup.h:106
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
StringRef P
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1294
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
PathDiagnosticLocation getLocation() const
PathDiagnostic - PathDiagnostic objects represent a single path-sensitive diagnostic.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:269
One of these records is kept for each identifier that is lexed.
Follow the default settings for inlining callees.
Definition: ExprEngine.h:89
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:150
Defines the clang::CodeInjector interface which is responsible for injecting AST of function definiti...
Definition: Format.h:2031
std::unique_ptr< StoreManager >(* StoreManagerCreator)(ProgramStateManager &)
Definition: ProgramState.h:44
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
const LangOptions & getLangOpts() const
Definition: Preprocessor.h:821
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2222
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
Definition: DeclObjC.cpp:940
FrontendOptions & getFrontendOpts()
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:149
iterator begin()
Definition: DeclGroup.h:100
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
AnalyzerOptionsRef getAnalyzerOpts()
Decl * getDecl() const
Definition: CallGraph.h:173
param_iterator param_begin()
Definition: Decl.h:2234
std::unique_ptr< ConstraintManager >(* ConstraintManagerCreator)(ProgramStateManager &, SubEngine *)
Definition: ProgramState.h:42
StringRef Filename
Definition: Format.cpp:1604
static bool shouldSkipFunction(const Decl *D, const SetOfConstDecls &Visited, const SetOfConstDecls &VisitedAsTopLevel)
std::unique_ptr< CheckerManager > createCheckerManager(AnalyzerOptions &opts, const LangOptions &langOpts, ArrayRef< std::string > plugins, ArrayRef< std::function< void(CheckerRegistry &)>> checkerRegistrationFns, DiagnosticsEngine &diags)
InliningModes
The modes of inlining, which override the default analysis-wide settings.
Definition: ExprEngine.h:87
bool isValid() const
Pepresents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:3842
CFG - Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Definition: CFG.h:1002
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
unsigned getLine() const
Return the presumed line number of this location.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2017
Defines the clang::Preprocessor interface.
This file defines the clang::ento::ModelInjector class which implements the clang::CodeInjector inter...
void FlushReports()
Generate and flush diagnostics for all bug reports.
Represents an unpacked "presumed" location which can be presented to the user.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1040
PathPieces flatten(bool ShouldFlattenMacros) const
const SourceManager & SM
Definition: Format.cpp:1474
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
Definition: DeclBase.h:990
const char * getFilename() const
Return the presumed filename of this location.
BugReporter is a utility class for generating PathDiagnostics for analysis.
Definition: BugReporter.h:412
#define false
Definition: stdbool.h:33
llvm::MemoryBuffer * getBuffer(FileID FID, SourceLocation Loc, bool *Invalid=nullptr) const
Return the buffer for the specified FileID.
unsigned getColumn() const
Return the presumed column number of this location.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Encodes a location in the source.
STATISTIC(NumFunctionTopLevel, "The # of functions at top level.")
std::vector< PathDiagnosticConsumer * > PathDiagnosticConsumers
BugReporter & getBugReporter()
Definition: ExprEngine.h:192
Do minimal inlining of callees.
Definition: ExprEngine.h:92
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:775
StringRef getName() const
Return the actual identifier string.
bool ExecuteWorkList(const LocationContext *L, unsigned Steps=150000)
Returns true if there is still simulation state on the worklist.
Definition: ExprEngine.h:167
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Dataflow Directional Tag Classes.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1262
CodeInjector is an interface which is responsible for injecting AST of function definitions that may ...
Definition: CodeInjector.h:36
FileID getMainFileID() const
Returns the FileID of the main source file.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
This class is used for tools that requires cross translation unit capability.
std::unique_ptr< AnalysisASTConsumer > CreateAnalysisConsumer(CompilerInstance &CI)
CreateAnalysisConsumer - Creates an ASTConsumer to run various code analysis passes.
void setWarningsAsErrors(bool Val)
When set to true, any warnings reported are issued as errors.
Definition: Diagnostic.h:606
static std::unique_ptr< ExplodedNode::Auditor > CreateUbiViz()
static void SetAuditor(Auditor *A)
SourceManager & getSourceManager()
Definition: ASTContext.h:645
bool hasFatalErrorOccurred() const
Definition: Diagnostic.h:753
Preprocessor & getPreprocessor() const
Return the current preprocessor.
static bool isBisonFile(ASTContext &C)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:991
DiagnosticsEngine & getDiagnostics() const
Definition: Preprocessor.h:818
void addToCallGraph(Decl *D)
Populate the call graph with the functions in the given declaration.
Definition: CallGraph.h:62
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1500
The top declaration context.
Definition: Decl.h:107
std::deque< Decl * > SetOfDecls
void ViewGraph(bool trim=false)
Visualize the ExplodedGraph created by executing the simulation.
SourceLocation getLocStart() const LLVM_READONLY
Definition: Stmt.cpp:278
This class handles loading and caching of source files into memory.
SourceLocation getLocation() const
Definition: DeclBase.h:417
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:127
StringRef getShortDescription() const