Coverage Report

Created: 2021-01-19 06:58

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
Line
Count
Source (jump to first uncovered line)
1
//===- AnalyzerOptions.h - Analysis Engine Options --------------*- C++ -*-===//
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
// This header defines various options for the static analyzer that are set
10
// by the frontend and are consulted throughout the analyzer.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
15
#define LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
16
17
#include "clang/Analysis/PathDiagnostic.h"
18
#include "clang/Basic/LLVM.h"
19
#include "llvm/ADT/IntrusiveRefCntPtr.h"
20
#include "llvm/ADT/Optional.h"
21
#include "llvm/ADT/StringMap.h"
22
#include "llvm/ADT/StringRef.h"
23
#include "llvm/ADT/StringSwitch.h"
24
#include <string>
25
#include <utility>
26
#include <vector>
27
28
namespace clang {
29
30
namespace ento {
31
32
class CheckerBase;
33
34
} // namespace ento
35
36
/// Analysis - Set of available source code analyses.
37
enum Analyses {
38
#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
39
#include "clang/StaticAnalyzer/Core/Analyses.def"
40
NumAnalyses
41
};
42
43
/// AnalysisStores - Set of available analysis store models.
44
enum AnalysisStores {
45
#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
46
#include "clang/StaticAnalyzer/Core/Analyses.def"
47
NumStores
48
};
49
50
/// AnalysisConstraints - Set of available constraint models.
51
enum AnalysisConstraints {
52
#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
53
#include "clang/StaticAnalyzer/Core/Analyses.def"
54
NumConstraints
55
};
56
57
/// AnalysisDiagClients - Set of available diagnostic clients for rendering
58
///  analysis results.
59
enum AnalysisDiagClients {
60
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
61
#include "clang/StaticAnalyzer/Core/Analyses.def"
62
PD_NONE,
63
NUM_ANALYSIS_DIAG_CLIENTS
64
};
65
66
/// AnalysisPurgeModes - Set of available strategies for dead symbol removal.
67
enum AnalysisPurgeMode {
68
#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME,
69
#include "clang/StaticAnalyzer/Core/Analyses.def"
70
NumPurgeModes
71
};
72
73
/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
74
enum AnalysisInliningMode {
75
#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
76
#include "clang/StaticAnalyzer/Core/Analyses.def"
77
NumInliningModes
78
};
79
80
/// Describes the different kinds of C++ member functions which can be
81
/// considered for inlining by the analyzer.
82
///
83
/// These options are cumulative; enabling one kind of member function will
84
/// enable all kinds with lower enum values.
85
enum CXXInlineableMemberKind {
86
  // Uninitialized = 0,
87
88
  /// A dummy mode in which no C++ inlining is enabled.
89
  CIMK_None,
90
91
  /// Refers to regular member function and operator calls.
92
  CIMK_MemberFunctions,
93
94
  /// Refers to constructors (implicit or explicit).
95
  ///
96
  /// Note that a constructor will not be inlined if the corresponding
97
  /// destructor is non-trivial.
98
  CIMK_Constructors,
99
100
  /// Refers to destructors (implicit or explicit).
101
  CIMK_Destructors
102
};
103
104
/// Describes the different modes of inter-procedural analysis.
105
enum IPAKind {
106
  /// Perform only intra-procedural analysis.
107
  IPAK_None = 1,
108
109
  /// Inline C functions and blocks when their definitions are available.
110
  IPAK_BasicInlining = 2,
111
112
  /// Inline callees(C, C++, ObjC) when their definitions are available.
113
  IPAK_Inlining = 3,
114
115
  /// Enable inlining of dynamically dispatched methods.
116
  IPAK_DynamicDispatch = 4,
117
118
  /// Enable inlining of dynamically dispatched methods, bifurcate paths when
119
  /// exact type info is unavailable.
120
  IPAK_DynamicDispatchBifurcate = 5
121
};
122
123
enum class ExplorationStrategyKind {
124
  DFS,
125
  BFS,
126
  UnexploredFirst,
127
  UnexploredFirstQueue,
128
  UnexploredFirstLocationQueue,
129
  BFSBlockDFSContents,
130
};
131
132
/// Describes the kinds for high-level analyzer mode.
133
enum UserModeKind {
134
  /// Perform shallow but fast analyzes.
135
  UMK_Shallow = 1,
136
137
  /// Perform deep analyzes.
138
  UMK_Deep = 2
139
};
140
141
/// Stores options for the analyzer from the command line.
142
///
143
/// Some options are frontend flags (e.g.: -analyzer-output), but some are
144
/// analyzer configuration options, which are preceded by -analyzer-config
145
/// (e.g.: -analyzer-config notes-as-events=true).
146
///
147
/// If you'd like to add a new frontend flag, add it to
148
/// include/clang/Driver/CC1Options.td, add a new field to store the value of
149
/// that flag in this class, and initialize it in
150
/// lib/Frontend/CompilerInvocation.cpp.
151
///
152
/// If you'd like to add a new non-checker configuration, register it in
153
/// include/clang/StaticAnalyzer/Core/AnalyzerOptions.def, and refer to the
154
/// top of the file for documentation.
155
///
156
/// If you'd like to add a new checker option, call getChecker*Option()
157
/// whenever.
158
///
159
/// Some of the options are controlled by raw frontend flags for no good reason,
160
/// and should be eventually converted into -analyzer-config flags. New analyzer
161
/// options should not be implemented as frontend flags. Frontend flags still
162
/// make sense for things that do not affect the actual analysis.
163
class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
164
public:
165
  using ConfigTable = llvm::StringMap<std::string>;
166
167
  /// Retrieves the list of checkers generated from Checkers.td. This doesn't
168
  /// contain statically linked but non-generated checkers and plugin checkers!
169
  static std::vector<StringRef>
170
  getRegisteredCheckers(bool IncludeExperimental = false);
171
172
  /// Retrieves the list of packages generated from Checkers.td. This doesn't
173
  /// contain statically linked but non-generated packages and plugin packages!
174
  static std::vector<StringRef>
175
  getRegisteredPackages(bool IncludeExperimental = false);
176
177
  /// Convenience function for printing options or checkers and their
178
  /// description in a formatted manner. If \p MinLineWidth is set to 0, no line
179
  /// breaks are introduced for the description.
180
  ///
181
  /// Format, depending whether the option name's length is less than
182
  /// \p EntryWidth:
183
  ///
184
  ///   <padding>EntryName<padding>Description
185
  ///   <---------padding--------->Description
186
  ///   <---------padding--------->Description
187
  ///
188
  ///   <padding>VeryVeryLongEntryName
189
  ///   <---------padding--------->Description
190
  ///   <---------padding--------->Description
191
  ///   ^~~~~~~~~InitialPad
192
  ///            ^~~~~~~~~~~~~~~~~~EntryWidth
193
  ///   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~MinLineWidth
194
  static void printFormattedEntry(llvm::raw_ostream &Out,
195
                                  std::pair<StringRef, StringRef> EntryDescPair,
196
                                  size_t InitialPad, size_t EntryWidth,
197
                                  size_t MinLineWidth = 0);
198
199
  /// Pairs of checker/package name and enable/disable.
200
  std::vector<std::pair<std::string, bool>> CheckersAndPackages;
201
202
  /// Vector of checker/package names which will not emit warnings.
203
  std::vector<std::string> SilencedCheckersAndPackages;
204
205
  /// A key-value table of use-specified configuration values.
206
  // TODO: This shouldn't be public.
207
  ConfigTable Config;
208
  AnalysisStores AnalysisStoreOpt = RegionStoreModel;
209
  AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel;
210
  AnalysisDiagClients AnalysisDiagOpt = PD_HTML;
211
  AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt;
212
213
  std::string AnalyzeSpecificFunction;
214
215
  /// File path to which the exploded graph should be dumped.
216
  std::string DumpExplodedGraphTo;
217
218
  /// Store full compiler invocation for reproducible instructions in the
219
  /// generated report.
220
  std::string FullCompilerInvocation;
221
222
  /// The maximum number of times the analyzer visits a block.
223
  unsigned maxBlockVisitOnPath;
224
225
  /// Disable all analyzer checkers.
226
  ///
227
  /// This flag allows one to disable analyzer checkers on the code processed by
228
  /// the given analysis consumer. Note, the code will get parsed and the
229
  /// command-line options will get checked.
230
  unsigned DisableAllCheckers : 1;
231
232
  unsigned ShowCheckerHelp : 1;
233
  unsigned ShowCheckerHelpAlpha : 1;
234
  unsigned ShowCheckerHelpDeveloper : 1;
235
236
  unsigned ShowCheckerOptionList : 1;
237
  unsigned ShowCheckerOptionAlphaList : 1;
238
  unsigned ShowCheckerOptionDeveloperList : 1;
239
240
  unsigned ShowEnabledCheckerList : 1;
241
  unsigned ShowConfigOptionsList : 1;
242
  unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
243
  unsigned AnalyzeAll : 1;
244
  unsigned AnalyzerDisplayProgress : 1;
245
  unsigned AnalyzeNestedBlocks : 1;
246
247
  unsigned eagerlyAssumeBinOpBifurcation : 1;
248
249
  unsigned TrimGraph : 1;
250
  unsigned visualizeExplodedGraphWithGraphViz : 1;
251
  unsigned UnoptimizedCFG : 1;
252
  unsigned PrintStats : 1;
253
254
  /// Do not re-analyze paths leading to exhausted nodes with a different
255
  /// strategy. We get better code coverage when retry is enabled.
256
  unsigned NoRetryExhausted : 1;
257
258
  /// Emit analyzer warnings as errors.
259
  bool AnalyzerWerror : 1;
260
261
  /// The inlining stack depth limit.
262
  unsigned InlineMaxStackDepth;
263
264
  /// The mode of function selection used during inlining.
265
  AnalysisInliningMode InliningMode = NoRedundancy;
266
267
  // Create a field for each -analyzer-config option.
268
#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \
269
                                             SHALLOW_VAL, DEEP_VAL)            \
270
  ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
271
272
#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \
273
  TYPE NAME;
274
275
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
276
#undef ANALYZER_OPTION
277
#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
278
279
  // Create an array of all -analyzer-config command line options. Sort it in
280
  // the constructor.
281
  std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = {
282
#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \
283
                                             SHALLOW_VAL, DEEP_VAL)            \
284
  ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
285
286
#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \
287
  llvm::StringLiteral(CMDFLAG),
288
289
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
290
#undef ANALYZER_OPTION
291
#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
292
  };
293
294
410
  bool isUnknownAnalyzerConfig(StringRef Name) const {
295
410
    assert(llvm::is_sorted(AnalyzerConfigCmdFlags));
296
297
410
    return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
298
410
                               AnalyzerConfigCmdFlags.end(), Name);
299
410
  }
300
301
  AnalyzerOptions()
302
      : DisableAllCheckers(false), ShowCheckerHelp(false),
303
        ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
304
        ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
305
        ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
306
        ShowConfigOptionsList(false), AnalyzeAll(false),
307
        AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
308
        eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
309
        visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
310
111k
        PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {
311
111k
    llvm::sort(AnalyzerConfigCmdFlags);
312
111k
  }
313
314
  /// Interprets an option's string value as a boolean. The "true" string is
315
  /// interpreted as true and the "false" string is interpreted as false.
316
  ///
317
  /// If an option value is not provided, returns the given \p DefaultVal.
318
  /// @param [in] CheckerName The *full name* of the checker. One may retrieve
319
  /// this from the checker object's field \c Name, or through \c
320
  /// CheckerManager::getCurrentCheckerName within the checker's registry
321
  /// function.
322
  /// Checker options are retrieved in the following format:
323
  /// `-analyzer-config CheckerName:OptionName=Value.
324
  /// @param [in] OptionName Name for option to retrieve.
325
  /// @param [in] SearchInParents If set to true and the searched option was not
326
  /// specified for the given checker the options for the parent packages will
327
  /// be searched as well. The inner packages take precedence over the outer
328
  /// ones.
329
  bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName,
330
                               bool SearchInParents = false) const;
331
332
  bool getCheckerBooleanOption(const ento::CheckerBase *C, StringRef OptionName,
333
                               bool SearchInParents = false) const;
334
335
  /// Interprets an option's string value as an integer value.
336
  ///
337
  /// If an option value is not provided, returns the given \p DefaultVal.
338
  /// @param [in] CheckerName The *full name* of the checker. One may retrieve
339
  /// this from the checker object's field \c Name, or through \c
340
  /// CheckerManager::getCurrentCheckerName within the checker's registry
341
  /// function.
342
  /// Checker options are retrieved in the following format:
343
  /// `-analyzer-config CheckerName:OptionName=Value.
344
  /// @param [in] OptionName Name for option to retrieve.
345
  /// @param [in] SearchInParents If set to true and the searched option was not
346
  /// specified for the given checker the options for the parent packages will
347
  /// be searched as well. The inner packages take precedence over the outer
348
  /// ones.
349
  int getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName,
350
                              bool SearchInParents = false) const;
351
352
  int getCheckerIntegerOption(const ento::CheckerBase *C, StringRef OptionName,
353
                              bool SearchInParents = false) const;
354
355
  /// Query an option's string value.
356
  ///
357
  /// If an option value is not provided, returns the given \p DefaultVal.
358
  /// @param [in] CheckerName The *full name* of the checker. One may retrieve
359
  /// this from the checker object's field \c Name, or through \c
360
  /// CheckerManager::getCurrentCheckerName within the checker's registry
361
  /// function.
362
  /// Checker options are retrieved in the following format:
363
  /// `-analyzer-config CheckerName:OptionName=Value.
364
  /// @param [in] OptionName Name for option to retrieve.
365
  /// @param [in] SearchInParents If set to true and the searched option was not
366
  /// specified for the given checker the options for the parent packages will
367
  /// be searched as well. The inner packages take precedence over the outer
368
  /// ones.
369
  StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName,
370
                                   bool SearchInParents = false) const;
371
372
  StringRef getCheckerStringOption(const ento::CheckerBase *C,
373
                                   StringRef OptionName,
374
                                   bool SearchInParents = false) const;
375
376
  /// Retrieves and sets the UserMode. This is a high-level option,
377
  /// which is used to set other low-level options. It is not accessible
378
  /// outside of AnalyzerOptions.
379
  UserModeKind getUserMode() const;
380
381
  ExplorationStrategyKind getExplorationStrategy() const;
382
383
  /// Returns the inter-procedural analysis mode.
384
  IPAKind getIPAMode() const;
385
386
  /// Returns the option controlling which C++ member functions will be
387
  /// considered for inlining.
388
  ///
389
  /// This is controlled by the 'c++-inlining' config option.
390
  ///
391
  /// \sa CXXMemberInliningMode
392
  bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
393
394
1.33k
  ento::PathDiagnosticConsumerOptions getDiagOpts() const {
395
1.33k
    return {FullCompilerInvocation,
396
1.33k
            ShouldDisplayMacroExpansions,
397
1.33k
            ShouldSerializeStats,
398
1.33k
            ShouldWriteStableReportFilename,
399
1.33k
            AnalyzerWerror,
400
1.33k
            ShouldApplyFixIts,
401
1.33k
            ShouldDisplayCheckerNameForText};
402
1.33k
  }
403
};
404
405
using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>;
406
407
//===----------------------------------------------------------------------===//
408
// We'll use AnalyzerOptions in the frontend, but we can't link the frontend
409
// with clangStaticAnalyzerCore, because clangStaticAnalyzerCore depends on
410
// clangFrontend.
411
//
412
// For this reason, implement some methods in this header file.
413
//===----------------------------------------------------------------------===//
414
415
203k
inline UserModeKind AnalyzerOptions::getUserMode() const {
416
203k
  auto K = llvm::StringSwitch<llvm::Optional<UserModeKind>>(UserMode)
417
203k
    .Case("shallow", UMK_Shallow)
418
203k
    .Case("deep", UMK_Deep)
419
203k
    .Default(None);
420
203k
  assert(K.hasValue() && "User mode is invalid.");
421
203k
  return K.getValue();
422
203k
}
423
424
inline std::vector<StringRef>
425
10
AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
426
10
  static constexpr llvm::StringLiteral StaticAnalyzerCheckerNames[] = {
427
10
#define GET_CHECKERS
428
10
#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN)                 \
429
1.85k
  llvm::StringLiteral(FULLNAME),
430
10
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
431
10
#undef CHECKER
432
10
#undef GET_CHECKERS
433
10
  };
434
10
  std::vector<StringRef> Checkers;
435
1.85k
  for (StringRef CheckerName : StaticAnalyzerCheckerNames) {
436
1.85k
    if (!CheckerName.startswith("debug.") &&
437
1.63k
        (IncludeExperimental || 
!CheckerName.startswith("alpha.")163
))
438
1.57k
      Checkers.push_back(CheckerName);
439
1.85k
  }
440
10
  return Checkers;
441
10
}
442
443
inline std::vector<StringRef>
444
8
AnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) {
445
8
  static constexpr llvm::StringLiteral StaticAnalyzerPackageNames[] = {
446
8
#define GET_PACKAGES
447
392
#define PACKAGE(FULLNAME) llvm::StringLiteral(FULLNAME),
448
8
#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
449
8
#undef PACKAGE
450
8
#undef GET_PACKAGES
451
8
  };
452
8
  std::vector<StringRef> Packages;
453
392
  for (StringRef PackageName : StaticAnalyzerPackageNames) {
454
392
    if (PackageName != "debug" &&
455
384
        (IncludeExperimental || 
PackageName != "alpha"0
))
456
384
      Packages.push_back(PackageName);
457
392
  }
458
8
  return Packages;
459
8
}
460
461
} // namespace clang
462
463
#endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H