Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:10

0001 //===- AnalyzerOptions.h - Analysis Engine Options --------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This header defines various options for the static analyzer that are set
0010 // by the frontend and are consulted throughout the analyzer.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
0015 #define LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H
0016 
0017 #include "clang/Analysis/PathDiagnostic.h"
0018 #include "clang/Basic/LLVM.h"
0019 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0020 #include "llvm/ADT/StringMap.h"
0021 #include "llvm/ADT/StringRef.h"
0022 #include <string>
0023 #include <utility>
0024 #include <vector>
0025 
0026 namespace clang {
0027 
0028 namespace ento {
0029 
0030 class CheckerBase;
0031 
0032 } // namespace ento
0033 
0034 /// AnalysisConstraints - Set of available constraint models.
0035 enum AnalysisConstraints {
0036 #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) NAME##Model,
0037 #include "clang/StaticAnalyzer/Core/Analyses.def"
0038 NumConstraints
0039 };
0040 
0041 /// AnalysisDiagClients - Set of available diagnostic clients for rendering
0042 ///  analysis results.
0043 enum AnalysisDiagClients {
0044 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME,
0045 #include "clang/StaticAnalyzer/Core/Analyses.def"
0046 PD_NONE,
0047 NUM_ANALYSIS_DIAG_CLIENTS
0048 };
0049 
0050 /// AnalysisPurgeModes - Set of available strategies for dead symbol removal.
0051 enum AnalysisPurgeMode {
0052 #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) NAME,
0053 #include "clang/StaticAnalyzer/Core/Analyses.def"
0054 NumPurgeModes
0055 };
0056 
0057 /// AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
0058 enum AnalysisInliningMode {
0059 #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) NAME,
0060 #include "clang/StaticAnalyzer/Core/Analyses.def"
0061 NumInliningModes
0062 };
0063 
0064 /// Describes the different kinds of C++ member functions which can be
0065 /// considered for inlining by the analyzer.
0066 ///
0067 /// These options are cumulative; enabling one kind of member function will
0068 /// enable all kinds with lower enum values.
0069 enum CXXInlineableMemberKind {
0070   // Uninitialized = 0,
0071 
0072   /// A dummy mode in which no C++ inlining is enabled.
0073   CIMK_None,
0074 
0075   /// Refers to regular member function and operator calls.
0076   CIMK_MemberFunctions,
0077 
0078   /// Refers to constructors (implicit or explicit).
0079   ///
0080   /// Note that a constructor will not be inlined if the corresponding
0081   /// destructor is non-trivial.
0082   CIMK_Constructors,
0083 
0084   /// Refers to destructors (implicit or explicit).
0085   CIMK_Destructors
0086 };
0087 
0088 /// Describes the different modes of inter-procedural analysis.
0089 enum IPAKind {
0090   /// Perform only intra-procedural analysis.
0091   IPAK_None = 1,
0092 
0093   /// Inline C functions and blocks when their definitions are available.
0094   IPAK_BasicInlining = 2,
0095 
0096   /// Inline callees(C, C++, ObjC) when their definitions are available.
0097   IPAK_Inlining = 3,
0098 
0099   /// Enable inlining of dynamically dispatched methods.
0100   IPAK_DynamicDispatch = 4,
0101 
0102   /// Enable inlining of dynamically dispatched methods, bifurcate paths when
0103   /// exact type info is unavailable.
0104   IPAK_DynamicDispatchBifurcate = 5
0105 };
0106 
0107 enum class ExplorationStrategyKind {
0108   DFS,
0109   BFS,
0110   UnexploredFirst,
0111   UnexploredFirstQueue,
0112   UnexploredFirstLocationQueue,
0113   BFSBlockDFSContents,
0114 };
0115 
0116 /// Describes the kinds for high-level analyzer mode.
0117 enum UserModeKind {
0118   /// Perform shallow but fast analyzes.
0119   UMK_Shallow = 1,
0120 
0121   /// Perform deep analyzes.
0122   UMK_Deep = 2
0123 };
0124 
0125 enum class CTUPhase1InliningKind { None, Small, All };
0126 
0127 class PositiveAnalyzerOption {
0128 public:
0129   constexpr PositiveAnalyzerOption() = default;
0130   constexpr PositiveAnalyzerOption(unsigned Value) : Value(Value) {
0131     assert(Value > 0 && "only positive values are accepted");
0132   }
0133   constexpr PositiveAnalyzerOption(const PositiveAnalyzerOption &) = default;
0134   constexpr PositiveAnalyzerOption &
0135   operator=(const PositiveAnalyzerOption &Other) {
0136     Value = Other.Value;
0137     return *this;
0138   }
0139 
0140   static constexpr std::optional<PositiveAnalyzerOption> create(unsigned Val) {
0141     if (Val == 0)
0142       return std::nullopt;
0143     return PositiveAnalyzerOption{Val};
0144   }
0145   static std::optional<PositiveAnalyzerOption> create(StringRef Str) {
0146     unsigned Parsed = 0;
0147     if (Str.getAsInteger(0, Parsed))
0148       return std::nullopt;
0149     return PositiveAnalyzerOption::create(Parsed);
0150   }
0151   constexpr operator unsigned() const { return Value; }
0152 
0153 private:
0154   unsigned Value = 1;
0155 };
0156 
0157 /// Stores options for the analyzer from the command line.
0158 ///
0159 /// Some options are frontend flags (e.g.: -analyzer-output), but some are
0160 /// analyzer configuration options, which are preceded by -analyzer-config
0161 /// (e.g.: -analyzer-config notes-as-events=true).
0162 ///
0163 /// If you'd like to add a new frontend flag, add it to
0164 /// include/clang/Driver/CC1Options.td, add a new field to store the value of
0165 /// that flag in this class, and initialize it in
0166 /// lib/Frontend/CompilerInvocation.cpp.
0167 ///
0168 /// If you'd like to add a new non-checker configuration, register it in
0169 /// include/clang/StaticAnalyzer/Core/AnalyzerOptions.def, and refer to the
0170 /// top of the file for documentation.
0171 ///
0172 /// If you'd like to add a new checker option, call getChecker*Option()
0173 /// whenever.
0174 ///
0175 /// Some of the options are controlled by raw frontend flags for no good reason,
0176 /// and should be eventually converted into -analyzer-config flags. New analyzer
0177 /// options should not be implemented as frontend flags. Frontend flags still
0178 /// make sense for things that do not affect the actual analysis.
0179 class AnalyzerOptions : public RefCountedBase<AnalyzerOptions> {
0180 public:
0181   using ConfigTable = llvm::StringMap<std::string>;
0182 
0183   /// Retrieves the list of checkers generated from Checkers.td. This doesn't
0184   /// contain statically linked but non-generated checkers and plugin checkers!
0185   static std::vector<StringRef>
0186   getRegisteredCheckers(bool IncludeExperimental = false);
0187 
0188   /// Retrieves the list of packages generated from Checkers.td. This doesn't
0189   /// contain statically linked but non-generated packages and plugin packages!
0190   static std::vector<StringRef>
0191   getRegisteredPackages(bool IncludeExperimental = false);
0192 
0193   /// Convenience function for printing options or checkers and their
0194   /// description in a formatted manner. If \p MinLineWidth is set to 0, no line
0195   /// breaks are introduced for the description.
0196   ///
0197   /// Format, depending whether the option name's length is less than
0198   /// \p EntryWidth:
0199   ///
0200   ///   <padding>EntryName<padding>Description
0201   ///   <---------padding--------->Description
0202   ///   <---------padding--------->Description
0203   ///
0204   ///   <padding>VeryVeryLongEntryName
0205   ///   <---------padding--------->Description
0206   ///   <---------padding--------->Description
0207   ///   ^~~~~~~~~InitialPad
0208   ///            ^~~~~~~~~~~~~~~~~~EntryWidth
0209   ///   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~MinLineWidth
0210   static void printFormattedEntry(llvm::raw_ostream &Out,
0211                                   std::pair<StringRef, StringRef> EntryDescPair,
0212                                   size_t InitialPad, size_t EntryWidth,
0213                                   size_t MinLineWidth = 0);
0214 
0215   /// Pairs of checker/package name and enable/disable.
0216   std::vector<std::pair<std::string, bool>> CheckersAndPackages;
0217 
0218   /// Vector of checker/package names which will not emit warnings.
0219   std::vector<std::string> SilencedCheckersAndPackages;
0220 
0221   /// A key-value table of use-specified configuration values.
0222   // TODO: This shouldn't be public.
0223   ConfigTable Config;
0224   AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel;
0225   AnalysisDiagClients AnalysisDiagOpt = PD_HTML;
0226   AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt;
0227 
0228   std::string AnalyzeSpecificFunction;
0229 
0230   /// File path to which the exploded graph should be dumped.
0231   std::string DumpExplodedGraphTo;
0232 
0233   /// Store full compiler invocation for reproducible instructions in the
0234   /// generated report.
0235   std::string FullCompilerInvocation;
0236 
0237   /// The maximum number of times the analyzer visits a block.
0238   unsigned maxBlockVisitOnPath;
0239 
0240   /// Disable all analyzer checkers.
0241   ///
0242   /// This flag allows one to disable analyzer checkers on the code processed by
0243   /// the given analysis consumer. Note, the code will get parsed and the
0244   /// command-line options will get checked.
0245   unsigned DisableAllCheckers : 1;
0246 
0247   unsigned ShowCheckerHelp : 1;
0248   unsigned ShowCheckerHelpAlpha : 1;
0249   unsigned ShowCheckerHelpDeveloper : 1;
0250 
0251   unsigned ShowCheckerOptionList : 1;
0252   unsigned ShowCheckerOptionAlphaList : 1;
0253   unsigned ShowCheckerOptionDeveloperList : 1;
0254 
0255   unsigned ShowEnabledCheckerList : 1;
0256   unsigned ShowConfigOptionsList : 1;
0257   unsigned ShouldEmitErrorsOnInvalidConfigValue : 1;
0258   unsigned AnalyzeAll : 1;
0259   unsigned AnalyzerDisplayProgress : 1;
0260   unsigned AnalyzerNoteAnalysisEntryPoints : 1;
0261 
0262   unsigned TrimGraph : 1;
0263   unsigned visualizeExplodedGraphWithGraphViz : 1;
0264   unsigned UnoptimizedCFG : 1;
0265   unsigned PrintStats : 1;
0266 
0267   /// Do not re-analyze paths leading to exhausted nodes with a different
0268   /// strategy. We get better code coverage when retry is enabled.
0269   unsigned NoRetryExhausted : 1;
0270 
0271   /// Emit analyzer warnings as errors.
0272   bool AnalyzerWerror : 1;
0273 
0274   /// The inlining stack depth limit.
0275   unsigned InlineMaxStackDepth;
0276 
0277   /// The mode of function selection used during inlining.
0278   AnalysisInliningMode InliningMode = NoRedundancy;
0279 
0280   // Create a field for each -analyzer-config option.
0281 #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \
0282                                              SHALLOW_VAL, DEEP_VAL)            \
0283   ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
0284 
0285 #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \
0286   TYPE NAME;
0287 
0288 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
0289 #undef ANALYZER_OPTION
0290 #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
0291 
0292   bool isUnknownAnalyzerConfig(llvm::StringRef Name) {
0293     static std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = []() {
0294       // Create an array of all -analyzer-config command line options.
0295       std::vector<llvm::StringLiteral> AnalyzerConfigCmdFlags = {
0296 #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,        \
0297                                              SHALLOW_VAL, DEEP_VAL)            \
0298   ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
0299 
0300 #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)                \
0301   llvm::StringLiteral(CMDFLAG),
0302 
0303 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
0304 #undef ANALYZER_OPTION
0305 #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE
0306       };
0307       // FIXME: Sort this at compile-time when we get constexpr sort (C++20).
0308       llvm::sort(AnalyzerConfigCmdFlags);
0309       return AnalyzerConfigCmdFlags;
0310     }();
0311 
0312     return !std::binary_search(AnalyzerConfigCmdFlags.begin(),
0313                                AnalyzerConfigCmdFlags.end(), Name);
0314   }
0315 
0316   AnalyzerOptions()
0317       : DisableAllCheckers(false), ShowCheckerHelp(false),
0318         ShowCheckerHelpAlpha(false), ShowCheckerHelpDeveloper(false),
0319         ShowCheckerOptionList(false), ShowCheckerOptionAlphaList(false),
0320         ShowCheckerOptionDeveloperList(false), ShowEnabledCheckerList(false),
0321         ShowConfigOptionsList(false),
0322         ShouldEmitErrorsOnInvalidConfigValue(false), AnalyzeAll(false),
0323         AnalyzerDisplayProgress(false), AnalyzerNoteAnalysisEntryPoints(false),
0324         TrimGraph(false), visualizeExplodedGraphWithGraphViz(false),
0325         UnoptimizedCFG(false), PrintStats(false), NoRetryExhausted(false),
0326         AnalyzerWerror(false) {}
0327 
0328   /// Interprets an option's string value as a boolean. The "true" string is
0329   /// interpreted as true and the "false" string is interpreted as false.
0330   ///
0331   /// If an option value is not provided, returns the given \p DefaultVal.
0332   /// @param [in] CheckerName The *full name* of the checker. One may retrieve
0333   /// this from the checker object's field \c Name, or through \c
0334   /// CheckerManager::getCurrentCheckerName within the checker's registry
0335   /// function.
0336   /// Checker options are retrieved in the following format:
0337   /// `-analyzer-config CheckerName:OptionName=Value.
0338   /// @param [in] OptionName Name for option to retrieve.
0339   /// @param [in] SearchInParents If set to true and the searched option was not
0340   /// specified for the given checker the options for the parent packages will
0341   /// be searched as well. The inner packages take precedence over the outer
0342   /// ones.
0343   bool getCheckerBooleanOption(StringRef CheckerName, StringRef OptionName,
0344                                bool SearchInParents = false) const;
0345 
0346   bool getCheckerBooleanOption(const ento::CheckerBase *C, StringRef OptionName,
0347                                bool SearchInParents = false) const;
0348 
0349   /// Interprets an option's string value as an integer value.
0350   ///
0351   /// If an option value is not provided, returns the given \p DefaultVal.
0352   /// @param [in] CheckerName The *full name* of the checker. One may retrieve
0353   /// this from the checker object's field \c Name, or through \c
0354   /// CheckerManager::getCurrentCheckerName within the checker's registry
0355   /// function.
0356   /// Checker options are retrieved in the following format:
0357   /// `-analyzer-config CheckerName:OptionName=Value.
0358   /// @param [in] OptionName Name for option to retrieve.
0359   /// @param [in] SearchInParents If set to true and the searched option was not
0360   /// specified for the given checker the options for the parent packages will
0361   /// be searched as well. The inner packages take precedence over the outer
0362   /// ones.
0363   int getCheckerIntegerOption(StringRef CheckerName, StringRef OptionName,
0364                               bool SearchInParents = false) const;
0365 
0366   int getCheckerIntegerOption(const ento::CheckerBase *C, StringRef OptionName,
0367                               bool SearchInParents = false) const;
0368 
0369   /// Query an option's string value.
0370   ///
0371   /// If an option value is not provided, returns the given \p DefaultVal.
0372   /// @param [in] CheckerName The *full name* of the checker. One may retrieve
0373   /// this from the checker object's field \c Name, or through \c
0374   /// CheckerManager::getCurrentCheckerName within the checker's registry
0375   /// function.
0376   /// Checker options are retrieved in the following format:
0377   /// `-analyzer-config CheckerName:OptionName=Value.
0378   /// @param [in] OptionName Name for option to retrieve.
0379   /// @param [in] SearchInParents If set to true and the searched option was not
0380   /// specified for the given checker the options for the parent packages will
0381   /// be searched as well. The inner packages take precedence over the outer
0382   /// ones.
0383   StringRef getCheckerStringOption(StringRef CheckerName, StringRef OptionName,
0384                                    bool SearchInParents = false) const;
0385 
0386   StringRef getCheckerStringOption(const ento::CheckerBase *C,
0387                                    StringRef OptionName,
0388                                    bool SearchInParents = false) const;
0389 
0390   ExplorationStrategyKind getExplorationStrategy() const;
0391   CTUPhase1InliningKind getCTUPhase1Inlining() const;
0392 
0393   /// Returns the inter-procedural analysis mode.
0394   IPAKind getIPAMode() const;
0395 
0396   /// Returns the option controlling which C++ member functions will be
0397   /// considered for inlining.
0398   ///
0399   /// This is controlled by the 'c++-inlining' config option.
0400   ///
0401   /// \sa CXXMemberInliningMode
0402   bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const;
0403 
0404   ento::PathDiagnosticConsumerOptions getDiagOpts() const {
0405     return {FullCompilerInvocation,
0406             ShouldDisplayMacroExpansions,
0407             ShouldSerializeStats,
0408             // The stable report filename option is deprecated because
0409             // file names are now always stable. Now the old option acts as
0410             // an alias to the new verbose filename option because this
0411             // closely mimics the behavior under the old option.
0412             ShouldWriteStableReportFilename || ShouldWriteVerboseReportFilename,
0413             AnalyzerWerror,
0414             ShouldApplyFixIts,
0415             ShouldDisplayCheckerNameForText};
0416   }
0417 };
0418 
0419 using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>;
0420 
0421 //===----------------------------------------------------------------------===//
0422 // We'll use AnalyzerOptions in the frontend, but we can't link the frontend
0423 // with clangStaticAnalyzerCore, because clangStaticAnalyzerCore depends on
0424 // clangFrontend.
0425 //
0426 // For this reason, implement some methods in this header file.
0427 //===----------------------------------------------------------------------===//
0428 
0429 inline std::vector<StringRef>
0430 AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
0431   static constexpr llvm::StringLiteral StaticAnalyzerCheckerNames[] = {
0432 #define GET_CHECKERS
0433 #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN)                 \
0434   llvm::StringLiteral(FULLNAME),
0435 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
0436 #undef CHECKER
0437 #undef GET_CHECKERS
0438   };
0439   std::vector<StringRef> Checkers;
0440   for (StringRef CheckerName : StaticAnalyzerCheckerNames) {
0441     if (!CheckerName.starts_with("debug.") &&
0442         (IncludeExperimental || !CheckerName.starts_with("alpha.")))
0443       Checkers.push_back(CheckerName);
0444   }
0445   return Checkers;
0446 }
0447 
0448 inline std::vector<StringRef>
0449 AnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) {
0450   static constexpr llvm::StringLiteral StaticAnalyzerPackageNames[] = {
0451 #define GET_PACKAGES
0452 #define PACKAGE(FULLNAME) llvm::StringLiteral(FULLNAME),
0453 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
0454 #undef PACKAGE
0455 #undef GET_PACKAGES
0456   };
0457   std::vector<StringRef> Packages;
0458   for (StringRef PackageName : StaticAnalyzerPackageNames) {
0459     if (PackageName != "debug" &&
0460         (IncludeExperimental || PackageName != "alpha"))
0461       Packages.push_back(PackageName);
0462   }
0463   return Packages;
0464 }
0465 
0466 } // namespace clang
0467 
0468 #endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H