Coverage Report

Created: 2020-02-15 09:57

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