Coverage Report

Created: 2019-07-24 05:18

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