Coverage Report

Created: 2022-07-16 07:03

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