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 /// Analysis - Set of available source code analyses. 37 enum Analyses { 38 #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE) NAME, 39 #include "clang/StaticAnalyzer/Core/Analyses.def" 40 NumAnalyses 41 }; 42 43 /// AnalysisStores - Set of available analysis store models. 44 enum AnalysisStores { 45 #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) NAME##Model, 46 #include "clang/StaticAnalyzer/Core/Analyses.def" 47 NumStores 48 }; 49 50 /// AnalysisConstraints - Set of available constraint models. 51 enum AnalysisConstraints { 52 #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model, 53 #include "clang/StaticAnalyzer/Core/Analyses.def" 54 NumConstraints 55 }; 56 57 /// AnalysisDiagClients - Set of available diagnostic clients for rendering 58 /// analysis results. 59 enum AnalysisDiagClients { 60 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME, 61 #include "clang/StaticAnalyzer/Core/Analyses.def" 62 PD_NONE, 63 NUM_ANALYSIS_DIAG_CLIENTS 64 }; 65 66 /// AnalysisPurgeModes - Set of available strategies for dead symbol removal. 67 enum AnalysisPurgeMode { 68 #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME, 69 #include "clang/StaticAnalyzer/Core/Analyses.def" 70 NumPurgeModes 71 }; 72 73 /// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics. 74 enum AnalysisInliningMode { 75 #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME, 76 #include "clang/StaticAnalyzer/Core/Analyses.def" 77 NumInliningModes 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. 85 enum 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. 105 enum 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 123 enum 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. 133 enum 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. 163 class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> { 164 public: 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 405 using 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 415 inline 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 424 inline std::vector<StringRef> 425 AnalyzerOptions::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 443 inline std::vector<StringRef> 444 AnalyzerOptions::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