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 bool isUnknownAnalyzerConfig(StringRef Name) const { 281 assert(llvm::is_sorted(AnalyzerConfigCmdFlags)); 282 283 return !std::binary_search(AnalyzerConfigCmdFlags.begin(), 284 AnalyzerConfigCmdFlags.end(), Name); 285 } 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 AnalyzerWerror(false) { 297 llvm::sort(AnalyzerConfigCmdFlags); 298 } 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 {FullCompilerInvocation, 378 ShouldDisplayMacroExpansions, 379 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 ShouldWriteStableReportFilename || ShouldWriteVerboseReportFilename, 385 AnalyzerWerror, 386 ShouldApplyFixIts, 387 ShouldDisplayCheckerNameForText}; 388 } 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 AnalyzerOptions::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.startswith("debug.") && 414 (IncludeExperimental || !CheckerName.startswith("alpha."))) 415 Checkers.push_back(CheckerName); 416 } 417 return Checkers; 418 } 419 420 inline std::vector<StringRef> 421 AnalyzerOptions::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