Coverage Report

Created: 2020-02-25 14:32

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