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
28namespace clang {
29
30namespace ento {
31
32class CheckerBase;
33
34} // namespace ento
35
36/// Analysis - Set of available source code analyses.
37enum Analyses {
38#define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
39#include "clang/StaticAnalyzer/Core/Analyses.def"
40NumAnalyses
41};
42
43/// AnalysisStores - Set of available analysis store models.
44enum AnalysisStores {
45#define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
46#include "clang/StaticAnalyzer/Core/Analyses.def"
47NumStores
48};
49
50/// AnalysisConstraints - Set of available constraint models.
51enum AnalysisConstraints {
52#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
53#include "clang/StaticAnalyzer/Core/Analyses.def"
54NumConstraints
55};
56
57/// AnalysisDiagClients - Set of available diagnostic clients for rendering
58/// analysis results.
59enum AnalysisDiagClients {
60#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
61#include "clang/StaticAnalyzer/Core/Analyses.def"
62PD_NONE,
63NUM_ANALYSIS_DIAG_CLIENTS
64};
65
66/// AnalysisPurgeModes - Set of available strategies for dead symbol removal.
67enum AnalysisPurgeMode {
68#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME,
69#include "clang/StaticAnalyzer/Core/Analyses.def"
70NumPurgeModes
71};
72
73/// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
74enum AnalysisInliningMode {
75#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
76#include "clang/StaticAnalyzer/Core/Analyses.def"
77NumInliningModes
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.
85enum 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.
105enum 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
123enum 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.
133enum 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.
163class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
164public:
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 bool isUnknownAnalyzerConfig(StringRef Name) const {
295 assert(llvm::is_sorted(AnalyzerConfigCmdFlags));
296
297 return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
298 AnalyzerConfigCmdFlags.end(), Name);
299 }
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 PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {
311 llvm::sort(AnalyzerConfigCmdFlags);
312 }
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 ento::PathDiagnosticConsumerOptions getDiagOpts() const {
395 return {FullCompilerInvocation,
396 ShouldDisplayMacroExpansions,
397 ShouldSerializeStats,
398 ShouldWriteStableReportFilename,
399 AnalyzerWerror,
400 ShouldApplyFixIts,
401 ShouldDisplayCheckerNameForText};
402 }
403};
404
405using 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
415inline UserModeKind AnalyzerOptions::getUserMode() const {
416 auto K = llvm::StringSwitch<llvm::Optional<UserModeKind>>(UserMode)
417 .Case("shallow", UMK_Shallow)
418 .Case("deep", UMK_Deep)
419 .Default(None);
420 assert(K.hasValue() && "User mode is invalid.");
421 return K.getValue();
422}
423
424inline std::vector<StringRef>
425AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
426 static constexpr llvm::StringLiteral StaticAnalyzerCheckerNames[] = {
427#define GET_CHECKERS
428#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \
429 llvm::StringLiteral(FULLNAME),
430#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
431#undef CHECKER
432#undef GET_CHECKERS
433 };
434 std::vector<StringRef> Checkers;
435 for (StringRef CheckerName : StaticAnalyzerCheckerNames) {
436 if (!CheckerName.startswith("debug.") &&
437 (IncludeExperimental || !CheckerName.startswith("alpha.")))
438 Checkers.push_back(CheckerName);
439 }
440 return Checkers;
441}
442
443inline std::vector<StringRef>
444AnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) {
445 static constexpr llvm::StringLiteral StaticAnalyzerPackageNames[] = {
446#define GET_PACKAGES
447#define PACKAGE(FULLNAME) llvm::StringLiteral(FULLNAME),
448#include "clang/StaticAnalyzer/Checkers/Checkers.inc"
449#undef PACKAGE
450#undef GET_PACKAGES
451 };
452 std::vector<StringRef> Packages;
453 for (StringRef PackageName : StaticAnalyzerPackageNames) {
454 if (PackageName != "debug" &&
455 (IncludeExperimental || PackageName != "alpha"))
456 Packages.push_back(PackageName);
457 }
458 return Packages;
459}
460
461} // namespace clang
462
463#endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
464