Home | History | Annotate | Line # | Download | only in Core
      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