1 //===- AnalyzerOptions.h - Analysis Engine Options --------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This header defines various options for the static analyzer that are set
10 // by the frontend and are consulted throughout the analyzer.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
15 #define LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
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"
35 /// Analysis - Set of available source code analyses.
37 #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME,
38 #include "clang/StaticAnalyzer/Core/Analyses.def"
42 /// AnalysisStores - Set of available analysis store models.
44 #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
45 #include "clang/StaticAnalyzer/Core/Analyses.def"
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"
56 /// AnalysisDiagClients - Set of available diagnostic clients for rendering
58 enum AnalysisDiagClients {
59 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
60 #include "clang/StaticAnalyzer/Core/Analyses.def"
62 NUM_ANALYSIS_DIAG_CLIENTS
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"
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"
79 /// Describes the different kinds of C++ member functions which can be
80 /// considered for inlining by the analyzer.
82 /// These options are cumulative; enabling one kind of member function will
83 /// enable all kinds with lower enum values.
84 enum CXXInlineableMemberKind {
87 /// A dummy mode in which no C++ inlining is enabled.
90 /// Refers to regular member function and operator calls.
93 /// Refers to constructors (implicit or explicit).
95 /// Note that a constructor will not be inlined if the corresponding
96 /// destructor is non-trivial.
99 /// Refers to destructors (implicit or explicit).
103 /// Describes the different modes of inter-procedural analysis.
105 /// Perform only intra-procedural analysis.
108 /// Inline C functions and blocks when their definitions are available.
109 IPAK_BasicInlining = 2,
111 /// Inline callees(C, C++, ObjC) when their definitions are available.
114 /// Enable inlining of dynamically dispatched methods.
115 IPAK_DynamicDispatch = 4,
117 /// Enable inlining of dynamically dispatched methods, bifurcate paths when
118 /// exact type info is unavailable.
119 IPAK_DynamicDispatchBifurcate = 5
122 enum class ExplorationStrategyKind {
126 UnexploredFirstQueue,
127 UnexploredFirstLocationQueue,
131 /// Describes the kinds for high-level analyzer mode.
133 /// Perform shallow but fast analyzes.
136 /// Perform deep analyzes.
140 /// Stores options for the analyzer from the command line.
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).
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.
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.
155 /// If you'd like to add a new checker option, call getChecker*Option()
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> {
164 using ConfigTable = llvm::StringMap<std::string>;
166 static std::vector<StringRef>
167 getRegisteredCheckers(bool IncludeExperimental = false);
169 /// Convenience function for printing options or checkers and their
170 /// description in a formatted manner. If \p MinLineWidth is set to 0, no line
171 /// breaks are introduced for the description.
173 /// Format, depending whether the option name's length is less then
176 /// <padding>EntryName<padding>Description
177 /// <---------padding--------->Description
178 /// <---------padding--------->Description
180 /// <padding>VeryVeryLongOptionName
181 /// <---------padding--------->Description
182 /// <---------padding--------->Description
183 /// ^~~~~~~~ InitialPad
184 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~ EntryWidth
185 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~MinLineWidth
186 static void printFormattedEntry(
187 llvm::raw_ostream &Out,
188 std::pair<StringRef, StringRef> EntryDescPair,
189 size_t EntryWidth, size_t InitialPad, size_t MinLineWidth = 0);
192 /// Pair of checker name and enable/disable.
193 std::vector<std::pair<std::string, bool>> CheckersControlList;
195 /// A key-value table of use-specified configuration values.
196 // TODO: This shouldn't be public.
198 AnalysisStores AnalysisStoreOpt = RegionStoreModel;
199 AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel;
200 AnalysisDiagClients AnalysisDiagOpt = PD_HTML;
201 AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt;
203 std::string AnalyzeSpecificFunction;
205 /// File path to which the exploded graph should be dumped.
206 std::string DumpExplodedGraphTo;
208 /// Store full compiler invocation for reproducible instructions in the
209 /// generated report.
210 std::string FullCompilerInvocation;
212 /// The maximum number of times the analyzer visits a block.
213 unsigned maxBlockVisitOnPath;
215 /// Disable all analyzer checks.
217 /// This flag allows one to disable analyzer checks on the code processed by
218 /// the given analysis consumer. Note, the code will get parsed and the
219 /// command-line options will get checked.
220 unsigned DisableAllChecks : 1;
222 unsigned ShowCheckerHelp : 1;
223 unsigned ShowCheckerHelpAlpha : 1;
224 unsigned ShowCheckerHelpDeveloper : 1;
226 unsigned ShowCheckerOptionList : 1;
227 unsigned ShowCheckerOptionAlphaList : 1;
228 unsigned ShowCheckerOptionDeveloperList : 1;
230 unsigned ShowEnabledCheckerList : 1;
231 unsigned ShowConfigOptionsList : 1;
232 unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
233 unsigned AnalyzeAll : 1;
234 unsigned AnalyzerDisplayProgress : 1;
235 unsigned AnalyzeNestedBlocks : 1;
237 unsigned eagerlyAssumeBinOpBifurcation : 1;
239 unsigned TrimGraph : 1;
240 unsigned visualizeExplodedGraphWithGraphViz : 1;
241 unsigned UnoptimizedCFG : 1;
242 unsigned PrintStats : 1;
244 /// Do not re-analyze paths leading to exhausted nodes with a different
245 /// strategy. We get better code coverage when retry is enabled.
246 unsigned NoRetryExhausted : 1;
248 /// Emit analyzer warnings as errors.
249 unsigned AnalyzerWerror : 1;
251 /// The inlining stack depth limit.
252 // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls).
253 unsigned InlineMaxStackDepth = 5;
255 /// The mode of function selection used during inlining.
256 AnalysisInliningMode InliningMode = NoRedundancy;
258 // Create a field for each -analyzer-config option.
259 #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
260 SHALLOW_VAL, DEEP_VAL) \
261 ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
263 #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
266 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
267 #undef ANALYZER_OPTION
268 #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
270 // Create an array of all -analyzer-config command line options. Sort it in
272 std::vector<StringRef> AnalyzerConfigCmdFlags = {
273 #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
274 SHALLOW_VAL, DEEP_VAL) \
275 ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
277 #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
280 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
281 #undef ANALYZER_OPTION
282 #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
285 bool isUnknownAnalyzerConfig(StringRef Name) const {
287 assert(std::is_sorted(AnalyzerConfigCmdFlags.begin(),
288 AnalyzerConfigCmdFlags.end()));
290 return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
291 AnalyzerConfigCmdFlags.end(), Name);
295 : DisableAllChecks(false), ShowCheckerHelp(false),
296 ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
297 ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
298 ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
299 ShowConfigOptionsList(false), AnalyzeAll(false),
300 AnalyzerDisplayProgress(false), AnalyzeNestedBlocks(false),
301 eagerlyAssumeBinOpBifurcation(false), TrimGraph(false),
302 visualizeExplodedGraphWithGraphViz(false), UnoptimizedCFG(false),
303 PrintStats(false), NoRetryExhausted(false), AnalyzerWerror(false) {
304 llvm::sort(AnalyzerConfigCmdFlags);
307 /// Interprets an option's string value as a boolean. The "true" string is
308 /// interpreted as true and the "false" string is interpreted as false.
310 /// If an option value is not provided, returns the given \p DefaultVal.
311 /// @param [in] CheckerName The *full name* of the checker. One may retrieve
312 /// this from the checker object's field \c Name, or through \c
313 /// CheckerManager::getCurrentCheckName within the checker's registry
315 /// Checker options are retrieved in the following format:
316 /// `-analyzer-config CheckerName:OptionName=Value.
317 /// @param [in] OptionName Name for option to retrieve.
318 /// @param [in] SearchInParents If set to true and the searched option was not
319 /// specified for the given checker the options for the parent packages will
320 /// be searched as well. The inner packages take precedence over the outer
322 bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName,
323 bool SearchInParents = false) const;
325 bool getCheckerBooleanOption(const ento::CheckerBase *C, StringRef OptionName,
326 bool SearchInParents = false) const;
328 /// Interprets an option's string value as an integer value.
330 /// If an option value is not provided, returns the given \p DefaultVal.
331 /// @param [in] CheckerName The *full name* of the checker. One may retrieve
332 /// this from the checker object's field \c Name, or through \c
333 /// CheckerManager::getCurrentCheckName within the checker's registry
335 /// Checker options are retrieved in the following format:
336 /// `-analyzer-config CheckerName:OptionName=Value.
337 /// @param [in] OptionName Name for option to retrieve.
338 /// @param [in] SearchInParents If set to true and the searched option was not
339 /// specified for the given checker the options for the parent packages will
340 /// be searched as well. The inner packages take precedence over the outer
342 int getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName,
343 bool SearchInParents = false) const;
345 int getCheckerIntegerOption(const ento::CheckerBase *C, StringRef OptionName,
346 bool SearchInParents = false) const;
348 /// Query an option's string value.
350 /// If an option value is not provided, returns the given \p DefaultVal.
351 /// @param [in] CheckerName The *full name* of the checker. One may retrieve
352 /// this from the checker object's field \c Name, or through \c
353 /// CheckerManager::getCurrentCheckName within the checker's registry
355 /// Checker options are retrieved in the following format:
356 /// `-analyzer-config CheckerName:OptionName=Value.
357 /// @param [in] OptionName Name for option to retrieve.
358 /// @param [in] SearchInParents If set to true and the searched option was not
359 /// specified for the given checker the options for the parent packages will
360 /// be searched as well. The inner packages take precedence over the outer
362 StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName,
363 bool SearchInParents = false) const;
365 StringRef getCheckerStringOption(const ento::CheckerBase *C,
366 StringRef OptionName,
367 bool SearchInParents = false) const;
369 /// Retrieves and sets the UserMode. This is a high-level option,
370 /// which is used to set other low-level options. It is not accessible
371 /// outside of AnalyzerOptions.
372 UserModeKind getUserMode() const;
374 ExplorationStrategyKind getExplorationStrategy() const;
376 /// Returns the inter-procedural analysis mode.
377 IPAKind getIPAMode() const;
379 /// Returns the option controlling which C++ member functions will be
380 /// considered for inlining.
382 /// This is controlled by the 'c++-inlining' config option.
384 /// \sa CXXMemberInliningMode
385 bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
388 using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>;
390 //===----------------------------------------------------------------------===//
391 // We'll use AnalyzerOptions in the frontend, but we can't link the frontend
392 // with clangStaticAnalyzerCore, because clangStaticAnalyzerCore depends on
395 // For this reason, implement some methods in this header file.
396 //===----------------------------------------------------------------------===//
398 inline UserModeKind AnalyzerOptions::getUserMode() const {
399 auto K = llvm::StringSwitch<llvm::Optional<UserModeKind>>(UserMode)
400 .Case("shallow", UMK_Shallow)
401 .Case("deep", UMK_Deep)
403 assert(K.hasValue() && "User mode is invalid.");
409 #endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H