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/StringMap.h"
21#include "llvm/ADT/StringRef.h"
22#include <string>
23#include <utility>
24#include <vector>
25
26namespace clang {
27
28namespace ento {
29
30class CheckerBase;
31
32} // namespace ento
33
34/// AnalysisConstraints - Set of available constraint models.
35enum AnalysisConstraints {
36#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
37#include "clang/StaticAnalyzer/Core/Analyses.def"
38NumConstraints
39};
40
41/// AnalysisDiagClients - Set of available diagnostic clients for rendering
42/// analysis results.
43enum AnalysisDiagClients {
44#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
45#include "clang/StaticAnalyzer/Core/Analyses.def"
46PD_NONE,
47NUM_ANALYSIS_DIAG_CLIENTS
48};
49
50/// AnalysisPurgeModes - Set of available strategies for dead symbol removal.
51enum AnalysisPurgeMode {
52#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME,
53#include "clang/StaticAnalyzer/Core/Analyses.def"
54NumPurgeModes
55};
56
57/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
58enum AnalysisInliningMode {
59#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
60#include "clang/StaticAnalyzer/Core/Analyses.def"
61NumInliningModes
62};
63
64/// Describes the different kinds of C++ member functions which can be
65/// considered for inlining by the analyzer.
66///
67/// These options are cumulative; enabling one kind of member function will
68/// enable all kinds with lower enum values.
69enum CXXInlineableMemberKind {
70 // Uninitialized = 0,
71
72 /// A dummy mode in which no C++ inlining is enabled.
73 CIMK_None,
74
75 /// Refers to regular member function and operator calls.
76 CIMK_MemberFunctions,
77
78 /// Refers to constructors (implicit or explicit).
79 ///
80 /// Note that a constructor will not be inlined if the corresponding
81 /// destructor is non-trivial.
82 CIMK_Constructors,
83
84 /// Refers to destructors (implicit or explicit).
85 CIMK_Destructors
86};
87
88/// Describes the different modes of inter-procedural analysis.
89enum IPAKind {
90 /// Perform only intra-procedural analysis.
91 IPAK_None = 1,
92
93 /// Inline C functions and blocks when their definitions are available.
94 IPAK_BasicInlining = 2,
95
96 /// Inline callees(C, C++, ObjC) when their definitions are available.
97 IPAK_Inlining = 3,
98
99 /// Enable inlining of dynamically dispatched methods.
100 IPAK_DynamicDispatch = 4,
101
102 /// Enable inlining of dynamically dispatched methods, bifurcate paths when
103 /// exact type info is unavailable.
104 IPAK_DynamicDispatchBifurcate = 5
105};
106
107enum class ExplorationStrategyKind {
108 DFS,
109 BFS,
110 UnexploredFirst,
111 UnexploredFirstQueue,
112 UnexploredFirstLocationQueue,
113 BFSBlockDFSContents,
114};
115
116/// Describes the kinds for high-level analyzer mode.
117enum UserModeKind {
118 /// Perform shallow but fast analyzes.
119 UMK_Shallow = 1,
120
121 /// Perform deep analyzes.
122 UMK_Deep = 2
123};
124
125enum class CTUPhase1InliningKind { None, Small, All };
126
127/// Stores options for the analyzer from the command line.
128///
129/// Some options are frontend flags (e.g.: -analyzer-output), but some are
130/// analyzer configuration options, which are preceded by -analyzer-config
131/// (e.g.: -analyzer-config notes-as-events=true).
132///
133/// If you'd like to add a new frontend flag, add it to
134/// include/clang/Driver/CC1Options.td, add a new field to store the value of
135/// that flag in this class, and initialize it in
136/// lib/Frontend/CompilerInvocation.cpp.
137///
138/// If you'd like to add a new non-checker configuration, register it in
139/// include/clang/StaticAnalyzer/Core/AnalyzerOptions.def, and refer to the
140/// top of the file for documentation.
141///
142/// If you'd like to add a new checker option, call getChecker*Option()
143/// whenever.
144///
145/// Some of the options are controlled by raw frontend flags for no good reason,
146/// and should be eventually converted into -analyzer-config flags. New analyzer
147/// options should not be implemented as frontend flags. Frontend flags still
148/// make sense for things that do not affect the actual analysis.
149class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
150public:
151 using ConfigTable = llvm::StringMap<std::string>;
152
153 /// Retrieves the list of checkers generated from Checkers.td. This doesn't
154 /// contain statically linked but non-generated checkers and plugin checkers!
155 static std::vector<StringRef>
156 getRegisteredCheckers(bool IncludeExperimental = false);
157
158 /// Retrieves the list of packages generated from Checkers.td. This doesn't
159 /// contain statically linked but non-generated packages and plugin packages!
160 static std::vector<StringRef>
161 getRegisteredPackages(bool IncludeExperimental = false);
162
163 /// Convenience function for printing options or checkers and their
164 /// description in a formatted manner. If \p MinLineWidth is set to 0, no line
165 /// breaks are introduced for the description.
166 ///
167 /// Format, depending whether the option name's length is less than
168 /// \p EntryWidth:
169 ///
170 /// <padding>EntryName<padding>Description
171 /// <---------padding--------->Description
172 /// <---------padding--------->Description
173 ///
174 /// <padding>VeryVeryLongEntryName
175 /// <---------padding--------->Description
176 /// <---------padding--------->Description
177 /// ^~~~~~~~~InitialPad
178 /// ^~~~~~~~~~~~~~~~~~EntryWidth
179 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~MinLineWidth
180 static void printFormattedEntry(llvm::raw_ostream &Out,
181 std::pair<StringRef, StringRef> EntryDescPair,
182 size_t InitialPad, size_t EntryWidth,
183 size_t MinLineWidth = 0);
184
185 /// Pairs of checker/package name and enable/disable.
186 std::vector<std::pair<std::string, bool>> CheckersAndPackages;
187
188 /// Vector of checker/package names which will not emit warnings.
189 std::vector<std::string> SilencedCheckersAndPackages;
190
191 /// A key-value table of use-specified configuration values.
192 // TODO: This shouldn't be public.
193 ConfigTable Config;
194 AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel;
195 AnalysisDiagClients AnalysisDiagOpt = PD_HTML;
196 AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt;
197
198 std::string AnalyzeSpecificFunction;
199
200 /// File path to which the exploded graph should be dumped.
201 std::string DumpExplodedGraphTo;
202
203 /// Store full compiler invocation for reproducible instructions in the
204 /// generated report.
205 std::string FullCompilerInvocation;
206
207 /// The maximum number of times the analyzer visits a block.
208 unsigned maxBlockVisitOnPath;
209
210 /// Disable all analyzer checkers.
211 ///
212 /// This flag allows one to disable analyzer checkers on the code processed by
213 /// the given analysis consumer. Note, the code will get parsed and the
214 /// command-line options will get checked.
215 unsigned DisableAllCheckers : 1;
216
217 unsigned ShowCheckerHelp : 1;
218 unsigned ShowCheckerHelpAlpha : 1;
219 unsigned ShowCheckerHelpDeveloper : 1;
220
221 unsigned ShowCheckerOptionList : 1;
222 unsigned ShowCheckerOptionAlphaList : 1;
223 unsigned ShowCheckerOptionDeveloperList : 1;
224
225 unsigned ShowEnabledCheckerList : 1;
226 unsigned ShowConfigOptionsList : 1;
227 unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
228 unsigned AnalyzeAll : 1;
229 unsigned AnalyzerDisplayProgress : 1;
230 unsigned AnalyzerNoteAnalysisEntryPoints : 1;
231
232 unsigned eagerlyAssumeBinOpBifurcation : 1;
233
234 unsigned TrimGraph : 1;
235 unsigned visualizeExplodedGraphWithGraphViz : 1;
236 unsigned UnoptimizedCFG : 1;
237 unsigned PrintStats : 1;
238
239 /// Do not re-analyze paths leading to exhausted nodes with a different
240 /// strategy. We get better code coverage when retry is enabled.
241 unsigned NoRetryExhausted : 1;
242
243 /// Emit analyzer warnings as errors.
244 bool AnalyzerWerror : 1;
245
246 /// The inlining stack depth limit.
247 unsigned InlineMaxStackDepth;
248
249 /// The mode of function selection used during inlining.
250 AnalysisInliningMode InliningMode = NoRedundancy;
251
252 // Create a field for each -analyzer-config option.
253#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
254 SHALLOW_VAL, DEEP_VAL) \
255 ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
256
257#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
258 TYPE NAME;
259
260#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
261#undef ANALYZER_OPTION
262#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
263
264 bool isUnknownAnalyzerConfig(llvm::StringRef Name) {
265 static std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = []() {
266 // Create an array of all -analyzer-config command line options.
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 // FIXME: Sort this at compile-time when we get constexpr sort (C++20).
280 llvm::sort(C&: AnalyzerConfigCmdFlags);
281 return AnalyzerConfigCmdFlags;
282 }();
283
284 return !std::binary_search(first: AnalyzerConfigCmdFlags.begin(),
285 last: AnalyzerConfigCmdFlags.end(), val: Name);
286 }
287
288 AnalyzerOptions()
289 : DisableAllCheckers(false), ShowCheckerHelp(false),
290 ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
291 ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
292 ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
293 ShowConfigOptionsList(false),
294 ShouldEmitErrorsOnInvalidConfigValue(false), AnalyzeAll(false),
295 AnalyzerDisplayProgress(false), AnalyzerNoteAnalysisEntryPoints(false),
296 eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
297 visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
298 PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {}
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 ento::PathDiagnosticConsumerOptions getDiagOpts() const {
377 return {.ToolInvocation: FullCompilerInvocation,
378 .ShouldDisplayMacroExpansions: ShouldDisplayMacroExpansions,
379 .ShouldSerializeStats: 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 .ShouldWriteVerboseReportFilename: ShouldWriteStableReportFilename || ShouldWriteVerboseReportFilename,
385 .ShouldDisplayWarningsAsErrors: AnalyzerWerror,
386 .ShouldApplyFixIts: ShouldApplyFixIts,
387 .ShouldDisplayDiagnosticName: ShouldDisplayCheckerNameForText};
388 }
389};
390
391using 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
401inline std::vector<StringRef>
402AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
403 static constexpr llvm::StringLiteral StaticAnalyzerCheckerNames[] = {
404#define GET_CHECKERS
405#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
406 llvm::StringLiteral(FULLNAME),
407#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
408#undef CHECKER
409#undef GET_CHECKERS
410 };
411 std::vector<StringRef> Checkers;
412 for (StringRef CheckerName : StaticAnalyzerCheckerNames) {
413 if (!CheckerName.starts_with(Prefix: "debug.") &&
414 (IncludeExperimental || !CheckerName.starts_with(Prefix: "alpha.")))
415 Checkers.push_back(CheckerName);
416 }
417 return Checkers;
418}
419
420inline std::vector<StringRef>
421AnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) {
422 static constexpr llvm::StringLiteral StaticAnalyzerPackageNames[] = {
423#define GET_PACKAGES
424#define PACKAGE(FULLNAME) llvm::StringLiteral(FULLNAME),
425#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
426#undef PACKAGE
427#undef GET_PACKAGES
428 };
429 std::vector<StringRef> Packages;
430 for (StringRef PackageName : StaticAnalyzerPackageNames) {
431 if (PackageName != "debug" &&
432 (IncludeExperimental || PackageName != "alpha"))
433 Packages.push_back(PackageName);
434 }
435 return Packages;
436}
437
438} // namespace clang
439
440#endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
441

source code of clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h