From 549f9cd46f912a1b9e49fa88e348496fe9299382 Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Fri, 30 Nov 2018 20:44:00 +0000 Subject: [PATCH] [analyzer] Evaluate all non-checker config options before analysis In earlier patches regarding AnalyzerOptions, a lot of effort went into gathering all config options, and changing the interface so that potential misuse can be eliminited. Up until this point, AnalyzerOptions only evaluated an option when it was querried. For example, if we had a "-no-false-positives" flag, AnalyzerOptions would store an Optional field for it that would be None up until somewhere in the code until the flag's getter function is called. However, now that we're confident that we've gathered all configs, we can evaluate off of them before analysis, so we can emit a error on invalid input even if that prticular flag will not matter in that particular run of the analyzer. Another very big benefit of this is that debug.ConfigDumper will now show the value of all configs every single time. Also, almost all options related class have a similar interface, so uniformity is also a benefit. The implementation for errors on invalid input will be commited shorty. Differential Revision: https://reviews.llvm.org/D53692 llvm-svn: 348031 --- .../clang/StaticAnalyzer/Core/AnalyzerOptions.def | 425 ++++++++------------- .../clang/StaticAnalyzer/Core/AnalyzerOptions.h | 82 ++-- clang/lib/Frontend/CompilerInvocation.cpp | 63 +++ .../lib/StaticAnalyzer/Checkers/DebugCheckers.cpp | 4 +- .../lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 2 +- clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp | 21 +- clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp | 100 +---- clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 10 +- .../StaticAnalyzer/Core/BugReporterVisitors.cpp | 15 +- clang/lib/StaticAnalyzer/Core/CallEvent.cpp | 5 +- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 20 +- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp | 8 +- .../Core/ExprEngineCallAndReturn.cpp | 33 +- clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp | 2 +- clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp | 4 +- clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 2 +- clang/lib/StaticAnalyzer/Core/SValBuilder.cpp | 2 +- .../lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 2 +- .../StaticAnalyzer/Frontend/AnalysisConsumer.cpp | 4 +- .../lib/StaticAnalyzer/Frontend/ModelInjector.cpp | 2 +- clang/test/Analysis/analyzer-config.c | 35 +- clang/test/Analysis/analyzer-config.cpp | 36 +- 22 files changed, 381 insertions(+), 496 deletions(-) diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def index 03c83e7..6d9f948 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -9,29 +9,6 @@ // // This file defines the analyzer options avaible with -analyzer-config. // -// This file is in part intended for method generation. If it's not included -// for that purpose, the following function-like macros should be predefined, -// through which all registered options are accessible: -// -// * ANALYZER_OPTION: Register a new option. -// * ANALYZER_OPTION_DEPENDS_ON_USER_MODE: Register a new option, default -// value depends on the "user-mode" option. -// -// Options where a simple getter method is sufficient are registered with the -// following macros: -// -// * ANALYZER_OPTION_GEN_FN: Register a new option, and generate a getter -// method for it in AnalyzerOptions. -// -// * ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE: Same as above, but -// generates a getter function that depends on the "user-mode" option. -// -// You can only include this file when both or none of the above two macros -// are defined! -// When they are defined, entries that do not generate functions won't appear, -// and when they aren't, all entries are converted to ANALYZER_OPTION or to -// ANALYZER_OPTION_DEPENDS_ON_USER_MODE. -// //===----------------------------------------------------------------------===// #ifndef LLVM_ADT_STRINGREF_H @@ -53,22 +30,6 @@ define both 'ANALYZER_OPTION' and 'ANALYZER_OPTION_DEPENDS_ON_USER_MODE' macros! #endif #endif -#ifdef ANALYZER_OPTION_GEN_FN -#ifndef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE -#error If you include this file with the intent of generating functions, \ -define both 'ANALYZER_OPTION_GEN_FN' and \ -'ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE' macros! -#endif -#endif - -#ifdef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE -#ifndef ANALYZER_OPTION_GEN_FN -#error If you include this file with the intent of generating functions, \ -define both 'ANALYZER_OPTION_GEN_FN' and \ -'ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE' macros! -#endif -#endif - #ifndef ANALYZER_OPTION /// Create a new analyzer option, but dont generate a method for it in /// AnalyzerOptions. @@ -105,231 +66,187 @@ define both 'ANALYZER_OPTION_GEN_FN' and \ SHALLOW_VAL, DEEP_VAL) #endif -#ifndef ANALYZER_OPTION_GEN_FN -/// Create a new analyzer option, and generate a getter method for it in -/// AnalyzerOptions. -/// -/// TYPE - The type of the option object that will be stored in -/// AnalyzerOptions. This file is expected to be icluded in translation -/// units where AnalyzerOptions.h is included, so types from that -/// header should be used. -/// NAME - The name of the option object. -/// CMDFLAG - The command line flag for the option. -/// (-analyzer-config CMDFLAG=VALUE) -/// DESC - Description of the flag. -/// DEFAULT_VAL - The default value for CMDFLAG. -/// CREATE_FN - Name of the getter function. -// -// If this def file wasn't included with the intent of generating functions, -// regard all entries as ANALYZER_OPTION. -#define ANALYZER_OPTION_GEN_FN(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL, \ - CREATE_FN) \ - ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) -#endif +//===----------------------------------------------------------------------===// +// The "mode" option. Since some options depend on this, we list it on top of +// this file in order to make sure that the generated field for it is +// initialized before the rest. +//===----------------------------------------------------------------------===// -#ifndef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE -/// Create a new analyzer option, and generate a getter method for it in -/// AnalyzerOptions, and make it's default value depend on the "user-mode" -/// option. -/// -/// TYPE - The type of the option object that will be stored in -/// AnalyzerOptions. This file is expected to be icluded in translation -/// units where AnalyzerOptions.h is included, so types from that -/// header should be used. -/// NAME - The name of the option object. -/// CMDFLAG - The command line flag for the option. -/// (-analyzer-config CMDFLAG=VALUE) -/// DESC - Description of the flago. -/// SHALLOW_VAL - The default value for CMDFLAG, when "user-mode" was set to -/// "shallow". -/// DEEP_VAL - The default value for CMDFLAG, when "user-mode" was set to -/// "deep". -/// CREATE_FN - Name of the getter function. -// -// If this def file wasn't included with the intent of generating functions, -// regard all entries as ANALYZER_OPTION_DEPENDS_ON_USER_MODE. -#define ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE( \ - TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL, DEEP_VAL, CREATE_FN) \ - ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL, \ - DEEP_VAL) -#endif +ANALYZER_OPTION( + StringRef, UserMode, "mode", + "(string) Controls the high-level analyzer mode, which influences the " + "default settings for some of the lower-level config options (such as " + "IPAMode). Value: \"deep\", \"shallow\".", + "deep") //===----------------------------------------------------------------------===// // Boolean analyzer options. //===----------------------------------------------------------------------===// -ANALYZER_OPTION_GEN_FN(bool, IncludeImplicitDtorsInCFG, "cfg-implicit-dtors", - "Whether or not implicit destructors for C++ objects " - "should be included in the CFG.", - true, includeImplicitDtorsInCFG) +ANALYZER_OPTION(bool, ShouldIncludeImplicitDtorsInCFG, "cfg-implicit-dtors", + "Whether or not implicit destructors for C++ objects " + "should be included in the CFG.", + true) -ANALYZER_OPTION_GEN_FN(bool, IncludeTemporaryDtorsInCFG, "cfg-temporary-dtors", - "Whether or not the destructors for C++ temporary " - "objects should be included in the CFG.", - true, includeTemporaryDtorsInCFG) +ANALYZER_OPTION(bool, ShouldIncludeTemporaryDtorsInCFG, "cfg-temporary-dtors", + "Whether or not the destructors for C++ temporary " + "objects should be included in the CFG.", + true) -ANALYZER_OPTION_GEN_FN( - bool, IncludeLifetimeInCFG, "cfg-lifetime", +ANALYZER_OPTION( + bool, ShouldIncludeLifetimeInCFG, "cfg-lifetime", "Whether or not end-of-lifetime information should be included in the CFG.", - false, includeLifetimeInCFG) - -ANALYZER_OPTION_GEN_FN(bool, IncludeLoopExitInCFG, "cfg-loopexit", - "Whether or not the end of the loop information should " - "be included in the CFG.", - false, includeLoopExitInCFG) - -ANALYZER_OPTION_GEN_FN(bool, IncludeRichConstructorsInCFG, - "cfg-rich-constructors", - "Whether or not construction site information should be " - "included in the CFG C++ constructor elements.", - true, includeRichConstructorsInCFG) - -ANALYZER_OPTION_GEN_FN( - bool, IncludeScopesInCFG, "cfg-scopes", - "Whether or not scope information should be included in the CFG.", false, - includeScopesInCFG) - -ANALYZER_OPTION_GEN_FN( - bool, InlineTemplateFunctions, "c++-template-inlining", - "Whether or not templated functions may be considered for inlining.", true, - mayInlineTemplateFunctions) - -ANALYZER_OPTION_GEN_FN(bool, InlineCXXStandardLibrary, "c++-stdlib-inlining", - "Whether or not C++ standard library functions may be " - "considered for inlining.", - true, mayInlineCXXStandardLibrary) - -ANALYZER_OPTION_GEN_FN( - bool, InlineCXXAllocator, "c++-allocator-inlining", - "Whether or not allocator call may be considered for inlining.", true, - mayInlineCXXAllocator) - -ANALYZER_OPTION_GEN_FN( - bool, InlineCXXSharedPtrDtor, "c++-shared_ptr-inlining", + false) + +ANALYZER_OPTION(bool, ShouldIncludeLoopExitInCFG, "cfg-loopexit", + "Whether or not the end of the loop information should " + "be included in the CFG.", + false) + +ANALYZER_OPTION(bool, ShouldIncludeRichConstructorsInCFG, + "cfg-rich-constructors", + "Whether or not construction site information should be " + "included in the CFG C++ constructor elements.", + true) + +ANALYZER_OPTION( + bool, ShouldIncludeScopesInCFG, "cfg-scopes", + "Whether or not scope information should be included in the CFG.", false) + +ANALYZER_OPTION( + bool, MayInlineTemplateFunctions, "c++-template-inlining", + "Whether or not templated functions may be considered for inlining.", true) + +ANALYZER_OPTION(bool, MayInlineCXXStandardLibrary, "c++-stdlib-inlining", + "Whether or not C++ standard library functions may be " + "considered for inlining.", + true) + +ANALYZER_OPTION(bool, MayInlineCXXAllocator, "c++-allocator-inlining", + "Whether or not allocator call may be considered for inlining.", + true) + +ANALYZER_OPTION( + bool, MayInlineCXXSharedPtrDtor, "c++-shared_ptr-inlining", "Whether or not the destructor of C++ 'shared_ptr' may be considered for " "inlining. This covers std::shared_ptr, std::tr1::shared_ptr, and " "boost::shared_ptr, and indeed any destructor named '~shared_ptr'.", - false, mayInlineCXXSharedPtrDtor) + false) -ANALYZER_OPTION_GEN_FN(bool, InlineCXXTemporaryDtors, "c++-temp-dtor-inlining", - "Whether C++ temporary destructors should be inlined " - "during analysis. If temporary destructors are disabled " - "in the CFG via the 'cfg-temporary-dtors' option, " - "temporary destructors would not be inlined anyway.", - true, mayInlineCXXTemporaryDtors) +ANALYZER_OPTION(bool, MayInlineCXXTemporaryDtors, "c++-temp-dtor-inlining", + "Whether C++ temporary destructors should be inlined " + "during analysis. If temporary destructors are disabled " + "in the CFG via the 'cfg-temporary-dtors' option, " + "temporary destructors would not be inlined anyway.", + true) -ANALYZER_OPTION_GEN_FN( - bool, SuppressNullReturnPaths, "suppress-null-return-paths", +ANALYZER_OPTION( + bool, ShouldSuppressNullReturnPaths, "suppress-null-return-paths", "Whether or not paths that go through null returns should be suppressed. " "This is a heuristic for avoiding bug reports with paths that go through " "inlined functions that are more defensive than their callers.", - true, shouldSuppressNullReturnPaths) + true) -ANALYZER_OPTION_GEN_FN( - bool, AvoidSuppressingNullArgumentPaths, +ANALYZER_OPTION( + bool, ShouldAvoidSuppressingNullArgumentPaths, "avoid-suppressing-null-argument-paths", "Whether a bug report should not be suppressed if its path includes a call " "with a null argument, even if that call has a null return. This option " - "has no effect when #shouldSuppressNullReturnPaths() is false. This is a " + "has no effect when ShouldSuppressNullReturnPaths is false. This is a " "counter-heuristic to avoid false negatives.", - false, shouldAvoidSuppressingNullArgumentPaths) - -ANALYZER_OPTION_GEN_FN(bool, SuppressInlinedDefensiveChecks, - "suppress-inlined-defensive-checks", - "Whether or not diagnostics containing inlined " - "defensive NULL checks should be suppressed.", - true, shouldSuppressInlinedDefensiveChecks) - -ANALYZER_OPTION_GEN_FN(bool, InlineCXXContainerMethods, - "c++-container-inlining", - "Whether or not methods of C++ container objects may be " - "considered for inlining.", - false, mayInlineCXXContainerMethods) - -ANALYZER_OPTION_GEN_FN(bool, SuppressFromCXXStandardLibrary, - "suppress-c++-stdlib", - "Whether or not diagnostics reported within the C++ " - "standard library should be suppressed.", - true, shouldSuppressFromCXXStandardLibrary) - -ANALYZER_OPTION_GEN_FN(bool, CrosscheckWithZ3, "crosscheck-with-z3", - "Whether bug reports should be crosschecked with the Z3 " - "constraint manager backend.", - false, shouldCrosscheckWithZ3) - -ANALYZER_OPTION_GEN_FN(bool, ReportIssuesInMainSourceFile, - "report-in-main-source-file", - "Whether or not the diagnostic report should be always " - "reported in the main source file and not the headers.", - false, shouldReportIssuesInMainSourceFile) - -ANALYZER_OPTION_GEN_FN( - bool, WriteStableReportFilename, "stable-report-filename", - "Whether or not the report filename should be random or not.", false, - shouldWriteStableReportFilename) - -ANALYZER_OPTION_GEN_FN( - bool, SerializeStats, "serialize-stats", + false) + +ANALYZER_OPTION(bool, ShouldSuppressInlinedDefensiveChecks, + "suppress-inlined-defensive-checks", + "Whether or not diagnostics containing inlined " + "defensive NULL checks should be suppressed.", + true) + +ANALYZER_OPTION(bool, MayInlineCXXContainerMethods, "c++-container-inlining", + "Whether or not methods of C++ container objects may be " + "considered for inlining.", + false) + +ANALYZER_OPTION(bool, ShouldSuppressFromCXXStandardLibrary, + "suppress-c++-stdlib", + "Whether or not diagnostics reported within the C++ " + "standard library should be suppressed.", + true) + +ANALYZER_OPTION(bool, ShouldCrosscheckWithZ3, "crosscheck-with-z3", + "Whether bug reports should be crosschecked with the Z3 " + "constraint manager backend.", + false) + +ANALYZER_OPTION(bool, ShouldReportIssuesInMainSourceFile, + "report-in-main-source-file", + "Whether or not the diagnostic report should be always " + "reported in the main source file and not the headers.", + false) + +ANALYZER_OPTION(bool, ShouldWriteStableReportFilename, "stable-report-filename", + "Whether or not the report filename should be random or not.", + false) + +ANALYZER_OPTION( + bool, ShouldSerializeStats, "serialize-stats", "Whether the analyzer should serialize statistics to plist output. " "Statistics would be serialized in JSON format inside the main dictionary " "under the statistics key. Available only if compiled in assert mode or " "with LLVM statistics explicitly enabled.", - false, shouldSerializeStats) + false) -ANALYZER_OPTION_GEN_FN( - bool, InlineObjCMethod, "objc-inlining", - "Whether ObjectiveC inlining is enabled, false otherwise.", true, - mayInlineObjCMethod) +ANALYZER_OPTION(bool, MayInlineObjCMethod, "objc-inlining", + "Whether ObjectiveC inlining is enabled, false otherwise.", + true) -ANALYZER_OPTION_GEN_FN(bool, PrunePaths, "prune-paths", - "Whether irrelevant parts of a bug report path should " - "be pruned out of the final output.", - true, shouldPrunePaths) +ANALYZER_OPTION(bool, ShouldPrunePaths, "prune-paths", + "Whether irrelevant parts of a bug report path should " + "be pruned out of the final output.", + true) -ANALYZER_OPTION_GEN_FN( - bool, ConditionalizeStaticInitializers, +ANALYZER_OPTION( + bool, ShouldConditionalizeStaticInitializers, "cfg-conditional-static-initializers", "Whether 'static' initializers should be in conditional logic in the CFG.", - true, shouldConditionalizeStaticInitializers) + true) -ANALYZER_OPTION_GEN_FN(bool, SynthesizeBodies, "faux-bodies", - "Whether the analyzer engine should synthesize fake " - "bodies for well-known functions.", - true, shouldSynthesizeBodies) +ANALYZER_OPTION(bool, ShouldSynthesizeBodies, "faux-bodies", + "Whether the analyzer engine should synthesize fake " + "bodies for well-known functions.", + true) -ANALYZER_OPTION_GEN_FN( - bool, ElideConstructors, "elide-constructors", +ANALYZER_OPTION( + bool, ShouldElideConstructors, "elide-constructors", "Whether elidable C++ copy-constructors and move-constructors should be " "actually elided during analysis. Both behaviors are allowed by the C++ " "standard, and the analyzer, like CodeGen, defaults to eliding. Starting " "with C++17 some elisions become mandatory, and in these cases the option " "will be ignored.", - true, shouldElideConstructors) + true) -ANALYZER_OPTION_GEN_FN( - bool, InlineLambdas, "inline-lambdas", +ANALYZER_OPTION( + bool, ShouldInlineLambdas, "inline-lambdas", "Whether lambdas should be inlined. Otherwise a sink node will be " "generated each time a LambdaExpr is visited.", - true, shouldInlineLambdas) + true) -ANALYZER_OPTION_GEN_FN(bool, WidenLoops, "widen-loops", - "Whether the analysis should try to widen loops.", false, - shouldWidenLoops) +ANALYZER_OPTION(bool, ShouldWidenLoops, "widen-loops", + "Whether the analysis should try to widen loops.", false) -ANALYZER_OPTION_GEN_FN( - bool, UnrollLoops, "unroll-loops", - "Whether the analysis should try to unroll loops with known bounds.", false, - shouldUnrollLoops) +ANALYZER_OPTION( + bool, ShouldUnrollLoops, "unroll-loops", + "Whether the analysis should try to unroll loops with known bounds.", false) -ANALYZER_OPTION_GEN_FN( - bool, DisplayNotesAsEvents, "notes-as-events", +ANALYZER_OPTION( + bool, ShouldDisplayNotesAsEvents, "notes-as-events", "Whether the bug reporter should transparently treat extra note diagnostic " "pieces as event diagnostic pieces. Useful when the diagnostic consumer " "doesn't support the extra note pieces.", - false, shouldDisplayNotesAsEvents) + false) -ANALYZER_OPTION_GEN_FN( - bool, AggressivelySimplifyBinaryOperation, +ANALYZER_OPTION( + bool, ShouldAggressivelySimplifyBinaryOperation, "aggressive-binary-operation-simplification", "Whether SValBuilder should rearrange comparisons and additive operations " "of symbolic expressions which consist of a sum of a symbol and a concrete " @@ -342,10 +259,10 @@ ANALYZER_OPTION_GEN_FN( "'<', '<=', '>', '>=', '+' or '-'. The rearrangement also happens with '-' " "instead of '+' on either or both side and also if any or both integers " "are missing.", - false, shouldAggressivelySimplifyBinaryOperation) + false) -ANALYZER_OPTION_GEN_FN( - bool, EagerlyAssume, "eagerly-assume", +ANALYZER_OPTION( + bool, ShouldEagerlyAssume, "eagerly-assume", "Whether we should eagerly assume evaluations of conditionals, thus, " "bifurcating the path. This indicates how the engine should handle " "expressions such as: 'x = (y != 0)'. When this is true then the " @@ -353,69 +270,66 @@ ANALYZER_OPTION_GEN_FN( "evaluating it to the integers 0 or 1 respectively. The upside is that " "this can increase analysis precision until we have a better way to lazily " "evaluate such logic. The downside is that it eagerly bifurcates paths.", - true, shouldEagerlyAssume) + true) -ANALYZER_OPTION_GEN_FN( - bool, NaiveCTU, "experimental-enable-naive-ctu-analysis", +ANALYZER_OPTION( + bool, IsNaiveCTUEnabled, "experimental-enable-naive-ctu-analysis", "Whether naive cross translation unit analysis is enabled. This is an " "experimental feature to inline functions from another translation units.", - false, naiveCTUEnabled) + false) -ANALYZER_OPTION_GEN_FN(bool, DisplayMacroExpansions, "expand-macros", - "Whether macros related to the bugpath should be " - "expanded and included in the plist output.", - false, shouldDisplayMacroExpansions) +ANALYZER_OPTION(bool, ShouldDisplayMacroExpansions, "expand-macros", + "Whether macros related to the bugpath should be " + "expanded and included in the plist output.", + false) //===----------------------------------------------------------------------===// // Unsinged analyzer options. //===----------------------------------------------------------------------===// -ANALYZER_OPTION_GEN_FN( +ANALYZER_OPTION( unsigned, AlwaysInlineSize, "ipa-always-inline-size", "The size of the functions (in basic blocks), which should be considered " "to be small enough to always inline.", - 3, getAlwaysInlineSize) + 3) -ANALYZER_OPTION_GEN_FN( +ANALYZER_OPTION( unsigned, GraphTrimInterval, "graph-trim-interval", "How often nodes in the ExplodedGraph should be recycled to save memory. " "To disable node reclamation, set the option to 0.", - 1000, getGraphTrimInterval) + 1000) -ANALYZER_OPTION_GEN_FN( +ANALYZER_OPTION( unsigned, MinCFGSizeTreatFunctionsAsLarge, "min-cfg-size-treat-functions-as-large", "The number of basic blocks a function needs to have to be considered " "large for the 'max-times-inline-large' config option.", - 14, getMinCFGSizeTreatFunctionsAsLarge) + 14) -ANALYZER_OPTION_GEN_FN(unsigned, MaxSymbolComplexity, "max-symbol-complexity", - "The maximum complexity of symbolic constraint.", 35, - getMaxSymbolComplexity) +ANALYZER_OPTION(unsigned, MaxSymbolComplexity, "max-symbol-complexity", + "The maximum complexity of symbolic constraint.", 35) -ANALYZER_OPTION_GEN_FN(unsigned, MaxTimesInlineLarge, "max-times-inline-large", - "The maximum times a large function could be inlined.", - 32, getMaxTimesInlineLarge) +ANALYZER_OPTION(unsigned, MaxTimesInlineLarge, "max-times-inline-large", + "The maximum times a large function could be inlined.", 32) -ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE( +ANALYZER_OPTION_DEPENDS_ON_USER_MODE( unsigned, MaxInlinableSize, "max-inlinable-size", "The bound on the number of basic blocks in an inlined function.", - /* SHALLOW_VAL */ 4, /* DEEP_VAL */ 100, getMaxInlinableSize) + /* SHALLOW_VAL */ 4, /* DEEP_VAL */ 100) -ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE( +ANALYZER_OPTION_DEPENDS_ON_USER_MODE( unsigned, MaxNodesPerTopLevelFunction, "max-nodes", "The maximum number of nodes the analyzer can generate while exploring a " "top level function (for each exploded graph). 0 means no limit.", - /* SHALLOW_VAL */ 75000, /* DEEP_VAL */ 225000, - getMaxNodesPerTopLevelFunction) + /* SHALLOW_VAL */ 75000, /* DEEP_VAL */ 225000) -ANALYZER_OPTION_GEN_FN( +ANALYZER_OPTION( unsigned, RegionStoreSmallStructLimit, "region-store-small-struct-limit", "The largest number of fields a struct can have and still be considered " "small This is currently used to decide whether or not it is worth forcing " "a LazyCompoundVal on bind. To disable all small-struct-dependent " "behavior, set the option to 0.", - 2, getRegionStoreSmallStructLimit) + 2) //===----------------------------------------------------------------------===// // String analyzer options. @@ -424,23 +338,16 @@ ANALYZER_OPTION_GEN_FN( ANALYZER_OPTION(StringRef, CTUDir, "ctu-dir", "The directory containing the CTU related files.", "") -ANALYZER_OPTION_GEN_FN( - StringRef, CTUIndexName, "ctu-index-name", - "the name of the file containing the CTU index of functions.", - "externalFnMap.txt", getCTUIndexName) +ANALYZER_OPTION(StringRef, CTUIndexName, "ctu-index-name", + "the name of the file containing the CTU index of functions.", + "externalFnMap.txt") -ANALYZER_OPTION_GEN_FN( +ANALYZER_OPTION( StringRef, ModelPath, "model-path", "The analyzer can inline an alternative implementation written in C at the " "call site if the called function's body is not available. This is a path " "where to look for those alternative implementations (called models).", - "", getModelPath) - -ANALYZER_OPTION(StringRef, UserMode, "mode", - "Controls the high-level analyzer mode, which influences the " - "default settings for some of the lower-level config options " - "(such as IPAMode). Value: \"deep\", \"shallow\".", - "deep") + "") ANALYZER_OPTION( StringRef, CXXMemberInliningMode, "c++-inlining", @@ -461,7 +368,5 @@ ANALYZER_OPTION( "\"bfs_block_dfs_contents\".", "unexplored_first_queue") -#undef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE -#undef ANALYZER_OPTION_GEN_FN #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE #undef ANALYZER_OPTION diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index f2b27562..722626e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -20,6 +20,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" #include #include #include @@ -170,6 +171,7 @@ public: std::vector> CheckersControlList; /// A key-value table of use-specified configuration values. + // TODO: This shouldn't be public. ConfigTable Config; AnalysisStores AnalysisStoreOpt = RegionStoreModel; AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel; @@ -220,33 +222,17 @@ public: /// The mode of function selection used during inlining. AnalysisInliningMode InliningMode = NoRedundancy; -private: - -#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ - Optional NAME; #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \ SHALLOW_VAL, DEEP_VAL) \ - Optional NAME; + ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL) + +#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ + TYPE NAME; + #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" #undef ANALYZER_OPTION #undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE - /// Query an option's string value. - /// - /// If an option value is not provided, returns the given \p DefaultVal. - /// @param [in] OptionName Name for option to retrieve. - /// @param [in] DefaultVal Default value returned if no such option was - /// specified. - StringRef getStringOption(StringRef OptionName, StringRef DefaultVal); - - void initOption(Optional &V, StringRef Name, - StringRef DefaultVal); - - void initOption(Optional &V, StringRef Name, bool DefaultVal); - - void initOption(Optional &V, StringRef Name, - unsigned DefaultVal); -public: AnalyzerOptions() : DisableAllChecks(false), ShowCheckerHelp(false), ShowEnabledCheckerList(false), ShowConfigOptionsList(false), @@ -308,42 +294,15 @@ public: const ento::CheckerBase *C, bool SearchInParents = false) const; -#define ANALYZER_OPTION_GEN_FN(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL, \ - CREATE_FN) \ - TYPE CREATE_FN() { \ - initOption(NAME, CMDFLAG, DEFAULT_VAL); \ - return NAME.getValue(); \ - } - -#define ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE( \ - TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL, DEEP_VAL, CREATE_FN) \ - TYPE CREATE_FN() { \ - switch (getUserMode()) { \ - case UMK_Shallow: \ - initOption(NAME, CMDFLAG, SHALLOW_VAL); \ - break; \ - case UMK_Deep: \ - initOption(NAME, CMDFLAG, DEEP_VAL); \ - break; \ - } \ - \ - return NAME.getValue(); \ - } - -#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" - -#undef ANALYZER_OPTION_GEN_FN_DEPENDS_ON_USER_MODE -#undef ANALYZER_OPTION_WITH_FN - /// Retrieves and sets the UserMode. This is a high-level option, /// which is used to set other low-level options. It is not accessible /// outside of AnalyzerOptions. - UserModeKind getUserMode(); + UserModeKind getUserMode() const; - ExplorationStrategyKind getExplorationStrategy(); + ExplorationStrategyKind getExplorationStrategy() const; /// Returns the inter-procedural analysis mode. - IPAKind getIPAMode(); + IPAKind getIPAMode() const; /// Returns the option controlling which C++ member functions will be /// considered for inlining. @@ -351,13 +310,28 @@ public: /// This is controlled by the 'c++-inlining' config option. /// /// \sa CXXMemberInliningMode - bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K); - - StringRef getCTUDir(); + bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K) const; }; using AnalyzerOptionsRef = IntrusiveRefCntPtr; +//===----------------------------------------------------------------------===// +// We'll use AnalyzerOptions in the frontend, but we can't link the frontend +// with clangStaticAnalyzerCore, because clangStaticAnalyzerCore depends on +// clangFrontend. +// +// For this reason, implement some methods in this header file. +//===----------------------------------------------------------------------===// + +inline UserModeKind AnalyzerOptions::getUserMode() const { + auto K = llvm::StringSwitch>(UserMode) + .Case("shallow", UMK_Shallow) + .Case("deep", UMK_Deep) + .Default(None); + assert(K.hasValue() && "User mode is invalid."); + return K.getValue(); +} + } // namespace clang #endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index f511fdc..f90e930 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -181,6 +181,9 @@ static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, } } +static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, + DiagnosticsEngine &Diags); + static void getAllNoBuiltinFuncValues(ArgList &Args, std::vector &Funcs) { SmallVector Values; @@ -343,6 +346,8 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, } } + parseAnalyzerConfigs(Opts, Diags); + llvm::raw_string_ostream os(Opts.FullCompilerInvocation); for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) { if (i != 0) @@ -354,6 +359,64 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, return Success; } +static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config, + StringRef OptionName, StringRef DefaultVal) { + return Config.insert({OptionName, DefaultVal}).first->second; +} + +static void initOption(AnalyzerOptions::ConfigTable &Config, + StringRef &OptionField, StringRef Name, + StringRef DefaultVal) { + OptionField = getStringOption(Config, Name, DefaultVal); +} + +static void initOption(AnalyzerOptions::ConfigTable &Config, + bool &OptionField, StringRef Name, bool DefaultVal) { + // FIXME: We should emit a warning here if the value is something other than + // "true", "false", or the empty string (meaning the default value), + // but the AnalyzerOptions doesn't have access to a diagnostic engine. + OptionField = llvm::StringSwitch(getStringOption(Config, Name, + (DefaultVal ? "true" : "false"))) + .Case("true", true) + .Case("false", false) + .Default(DefaultVal); +} + +static void initOption(AnalyzerOptions::ConfigTable &Config, + unsigned &OptionField, StringRef Name, + unsigned DefaultVal) { + OptionField = DefaultVal; + bool HasFailed = getStringOption(Config, Name, std::to_string(DefaultVal)) + .getAsInteger(10, OptionField); + assert(!HasFailed && "analyzer-config option should be numeric"); + (void)HasFailed; +} + +static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, + DiagnosticsEngine &Diags) { + // TODO: Emit warnings for incorrect options. + // TODO: There's no need to store the entire configtable, it'd be plenty + // enough tostore checker options. + +#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \ + initOption(AnOpts.Config, AnOpts.NAME, CMDFLAG, DEFAULT_VAL); \ + +#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \ + SHALLOW_VAL, DEEP_VAL) \ + switch (AnOpts.getUserMode()) { \ + case UMK_Shallow: \ + initOption(AnOpts.Config, AnOpts.NAME, CMDFLAG, SHALLOW_VAL); \ + break; \ + case UMK_Deep: \ + initOption(AnOpts.Config, AnOpts.NAME, CMDFLAG, DEEP_VAL); \ + break; \ + } \ + +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def" +#undef ANALYZER_OPTION +#undef ANALYZER_OPTION_DEPENDS_ON_USER_MODE +} + static bool ParseMigratorArgs(MigratorOptions &Opts, ArgList &Args) { Opts.NoNSAllocReallocError = Args.hasArg(OPT_migrator_no_nsalloc_error); Opts.NoFinalizeRemoval = Args.hasArg(OPT_migrator_no_finalize_removal); diff --git a/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp index 810a33e..60027f4 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp @@ -182,7 +182,9 @@ public: llvm::errs() << "[config]\n"; for (unsigned I = 0, E = Keys.size(); I != E; ++I) - llvm::errs() << Keys[I]->getKey() << " = " << Keys[I]->second << '\n'; + llvm::errs() << Keys[I]->getKey() << " = " + << (Keys[I]->second.empty() ? "\"\"" : Keys[I]->second) + << '\n'; llvm::errs() << "[stats]\n" << "num-entries = " << Keys.size() << '\n'; } diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index c2b4e13..982c2f3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -1094,7 +1094,7 @@ void MallocChecker::processNewAllocation(const CXXNewExpr *NE, void MallocChecker::checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const { - if (!C.getAnalysisManager().getAnalyzerOptions().mayInlineCXXAllocator()) + if (!C.getAnalysisManager().getAnalyzerOptions().MayInlineCXXAllocator) processNewAllocation(NE, C, C.getSVal(NE)); } diff --git a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp index 5f45d26..7fb1c09 100644 --- a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp @@ -22,16 +22,21 @@ AnalysisManager::AnalysisManager(ASTContext &ASTCtx, DiagnosticsEngine &diags, AnalyzerOptions &Options, CodeInjector *injector) : AnaCtxMgr( - ASTCtx, Options.UnoptimizedCFG, Options.includeImplicitDtorsInCFG(), - /*AddInitializers=*/true, Options.includeTemporaryDtorsInCFG(), - Options.includeLifetimeInCFG(), + ASTCtx, Options.UnoptimizedCFG, + Options.ShouldIncludeImplicitDtorsInCFG, + /*AddInitializers=*/true, + Options.ShouldIncludeTemporaryDtorsInCFG, + Options.ShouldIncludeLifetimeInCFG, // Adding LoopExit elements to the CFG is a requirement for loop // unrolling. - Options.includeLoopExitInCFG() || Options.shouldUnrollLoops(), - Options.includeScopesInCFG(), Options.shouldSynthesizeBodies(), - Options.shouldConditionalizeStaticInitializers(), - /*addCXXNewAllocator=*/true, Options.includeRichConstructorsInCFG(), - Options.shouldElideConstructors(), injector), + Options.ShouldIncludeLoopExitInCFG || + Options.ShouldUnrollLoops, + Options.ShouldIncludeScopesInCFG, + Options.ShouldSynthesizeBodies, + Options.ShouldConditionalizeStaticInitializers, + /*addCXXNewAllocator=*/true, + Options.ShouldIncludeRichConstructorsInCFG, + Options.ShouldElideConstructors, injector), Ctx(ASTCtx), Diags(diags), LangOpts(ASTCtx.getLangOpts()), PathConsumers(PDC), CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), CheckerMgr(checkerMgr), diff --git a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp index 025deda..d9b63c2 100644 --- a/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ b/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -49,28 +49,11 @@ AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental /* = false */) { return Result; } -UserModeKind AnalyzerOptions::getUserMode() { - if (!UserMode.hasValue()) { - UserMode = getStringOption("mode", "deep"); - } - - auto K = llvm::StringSwitch>(*UserMode) - .Case("shallow", UMK_Shallow) - .Case("deep", UMK_Deep) - .Default(None); - assert(UserMode.hasValue() && "User mode is invalid."); - return K.getValue(); -} - ExplorationStrategyKind -AnalyzerOptions::getExplorationStrategy() { - if (!ExplorationStrategy.hasValue()) { - ExplorationStrategy = getStringOption("exploration_strategy", - "unexplored_first_queue"); - } +AnalyzerOptions::getExplorationStrategy() const { auto K = llvm::StringSwitch>( - *ExplorationStrategy) + ExplorationStrategy) .Case("dfs", ExplorationStrategyKind::DFS) .Case("bfs", ExplorationStrategyKind::BFS) .Case("unexplored_first", @@ -86,18 +69,8 @@ AnalyzerOptions::getExplorationStrategy() { return K.getValue(); } -IPAKind AnalyzerOptions::getIPAMode() { - if (!IPAMode.hasValue()) { - switch (getUserMode()) { - case UMK_Shallow: - IPAMode = getStringOption("ipa", "inlining"); - break; - case UMK_Deep: - IPAMode = getStringOption("ipa", "dynamic-bifurcate"); - break; - } - } - auto K = llvm::StringSwitch>(*IPAMode) +IPAKind AnalyzerOptions::getIPAMode() const { + auto K = llvm::StringSwitch>(IPAMode) .Case("none", IPAK_None) .Case("basic-inlining", IPAK_BasicInlining) .Case("inlining", IPAK_Inlining) @@ -110,17 +83,14 @@ IPAKind AnalyzerOptions::getIPAMode() { } bool -AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind Param) { - if (!CXXMemberInliningMode.hasValue()) { - CXXMemberInliningMode = getStringOption("c++-inlining", "destructors"); - } - +AnalyzerOptions::mayInlineCXXMemberFunction( + CXXInlineableMemberKind Param) const { if (getIPAMode() < IPAK_Inlining) return false; auto K = llvm::StringSwitch>( - *CXXMemberInliningMode) + CXXMemberInliningMode) .Case("constructors", CIMK_Constructors) .Case("destructors", CIMK_Destructors) .Case("methods", CIMK_MemberFunctions) @@ -132,50 +102,6 @@ AnalyzerOptions::mayInlineCXXMemberFunction(CXXInlineableMemberKind Param) { return *K >= Param; } -StringRef AnalyzerOptions::getStringOption(StringRef OptionName, - StringRef DefaultVal) { - return Config.insert({OptionName, DefaultVal}).first->second; -} - -static StringRef toString(bool B) { return (B ? "true" : "false"); } - -template -static StringRef toString(T) = delete; - -void AnalyzerOptions::initOption(Optional &V, StringRef Name, - StringRef DefaultVal) { - if (V.hasValue()) - return; - - V = getStringOption(Name, DefaultVal); -} - -void AnalyzerOptions::initOption(Optional &V, StringRef Name, - bool DefaultVal) { - if (V.hasValue()) - return; - - // FIXME: We should emit a warning here if the value is something other than - // "true", "false", or the empty string (meaning the default value), - // but the AnalyzerOptions doesn't have access to a diagnostic engine. - V = llvm::StringSwitch(getStringOption(Name, toString(DefaultVal))) - .Case("true", true) - .Case("false", false) - .Default(DefaultVal); -} - -void AnalyzerOptions::initOption(Optional &V, StringRef Name, - unsigned DefaultVal) { - if (V.hasValue()) - return; - - V = DefaultVal; - bool HasFailed = getStringOption(Name, std::to_string(DefaultVal)) - .getAsInteger(10, *V); - assert(!HasFailed && "analyzer-config option should be numeric"); - (void)HasFailed; -} - StringRef AnalyzerOptions::getCheckerStringOption(StringRef OptionName, StringRef DefaultVal, const CheckerBase *C, @@ -210,7 +136,8 @@ bool AnalyzerOptions::getCheckerBooleanOption(StringRef Name, bool DefaultVal, // but the AnalyzerOptions doesn't have access to a diagnostic engine. assert(C); return llvm::StringSwitch( - getCheckerStringOption(Name, toString(DefaultVal), C, SearchInParents)) + getCheckerStringOption(Name, DefaultVal ? "true" : "false", C, + SearchInParents)) .Case("true", true) .Case("false", false) .Default(DefaultVal); @@ -227,12 +154,3 @@ int AnalyzerOptions::getCheckerIntegerOption(StringRef Name, int DefaultVal, (void)HasFailed; return Ret; } - -StringRef AnalyzerOptions::getCTUDir() { - if (!CTUDir.hasValue()) { - CTUDir = getStringOption("ctu-dir", ""); - if (!llvm::sys::fs::is_directory(*CTUDir)) - CTUDir = ""; - } - return CTUDir.getValue(); -} diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 2b6bbeb..f84b6e6 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -1976,7 +1976,7 @@ static std::unique_ptr generatePathDiagnosticForConsumer( // Finally, prune the diagnostic path of uninteresting stuff. if (!PD->path.empty()) { - if (R->shouldPrunePath() && Opts.shouldPrunePaths()) { + if (R->shouldPrunePath() && Opts.ShouldPrunePaths) { bool stillHasNotes = removeUnneededCalls(PD->getMutablePieces(), R, LCM); assert(stillHasNotes); @@ -2007,7 +2007,7 @@ static std::unique_ptr generatePathDiagnosticForConsumer( removeEdgesToDefaultInitializers(PD->getMutablePieces()); } - if (GenerateDiagnostics && Opts.shouldDisplayMacroExpansions()) + if (GenerateDiagnostics && Opts.ShouldDisplayMacroExpansions) CompactMacroExpandedPieces(PD->getMutablePieces(), SM); return PD; @@ -2621,7 +2621,7 @@ std::pair> findValidReport( generateVisitorsDiagnostics(R, ErrorNode, BRC); if (R->isValid()) { - if (Opts.shouldCrosscheckWithZ3()) { + if (Opts.ShouldCrosscheckWithZ3) { // If crosscheck is enabled, remove all visitors, add the refutation // visitor and check again R->clearVisitors(); @@ -2963,7 +2963,7 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) { } PathPieces &Pieces = PD->getMutablePieces(); - if (getAnalyzerOptions().shouldDisplayNotesAsEvents()) { + if (getAnalyzerOptions().ShouldDisplayNotesAsEvents) { // For path diagnostic consumers that don't support extra notes, // we may optionally convert those to path notes. for (auto I = report->getNotes().rbegin(), @@ -3100,7 +3100,7 @@ BugReporter::generateDiagnosticForConsumerMap( // report location to the last piece in the main source file. AnalyzerOptions &Opts = getAnalyzerOptions(); for (auto const &P : *Out) - if (Opts.shouldReportIssuesInMainSourceFile() && !Opts.AnalyzeAll) + if (Opts.ShouldReportIssuesInMainSourceFile && !Opts.AnalyzeAll) P.second->resetDiagnosticLocationToMainFile(); return Out; diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 99069d8..da94b6e 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -676,8 +676,8 @@ public: bool EnableNullFPSuppression, BugReport &BR, const SVal V) { AnalyzerOptions &Options = N->getState()->getAnalysisManager().options; - if (EnableNullFPSuppression && Options.shouldSuppressNullReturnPaths() - && V.getAs()) + if (EnableNullFPSuppression && + Options.ShouldSuppressNullReturnPaths && V.getAs()) BR.addVisitor(llvm::make_unique( R->getAs(), V)); } @@ -808,7 +808,8 @@ public: AnalyzerOptions &Options = State->getAnalysisManager().options; bool EnableNullFPSuppression = false; - if (InEnableNullFPSuppression && Options.shouldSuppressNullReturnPaths()) + if (InEnableNullFPSuppression && + Options.ShouldSuppressNullReturnPaths) if (Optional RetLoc = RetVal.getAs()) EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue(); @@ -877,7 +878,7 @@ public: // future nodes. We want to emit a path note as well, in case // the report is resurrected as valid later on. if (EnableNullFPSuppression && - Options.shouldAvoidSuppressingNullArgumentPaths()) + Options.ShouldAvoidSuppressingNullArgumentPaths) Mode = MaybeUnsuppress; if (RetE->getType()->isObjCObjectPointerType()) { @@ -925,7 +926,7 @@ public: visitNodeMaybeUnsuppress(const ExplodedNode *N, BugReporterContext &BRC, BugReport &BR) { #ifndef NDEBUG - assert(Options.shouldAvoidSuppressingNullArgumentPaths()); + assert(Options.ShouldAvoidSuppressingNullArgumentPaths); #endif // Are we at the entry node for this call? @@ -1378,7 +1379,7 @@ SuppressInlineDefensiveChecksVisitor(DefinedSVal Value, const ExplodedNode *N) : V(Value) { // Check if the visitor is disabled. AnalyzerOptions &Options = N->getState()->getAnalysisManager().options; - if (!Options.shouldSuppressInlinedDefensiveChecks()) + if (!Options.ShouldSuppressInlinedDefensiveChecks) IsSatisfied = true; assert(N->getState()->isNull(V).isConstrainedTrue() && @@ -2219,7 +2220,7 @@ void LikelyFalsePositiveSuppressionBRVisitor::finalizeVisitor( // the user's fault, we currently don't report them very well, and // Note that this will not help for any other data structure libraries, like // TR1, Boost, or llvm/ADT. - if (Options.shouldSuppressFromCXXStandardLibrary()) { + if (Options.ShouldSuppressFromCXXStandardLibrary) { BR.markInvalid(getTag(), nullptr); return; } else { diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp index e0759d1..6f90ea0 100644 --- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp +++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp @@ -554,13 +554,14 @@ RuntimeDefinition AnyFunctionCall::getRuntimeDefinition() const { AnalyzerOptions &Opts = Engine->getAnalysisManager().options; // Try to get CTU definition only if CTUDir is provided. - if (!Opts.naiveCTUEnabled()) + if (!Opts.IsNaiveCTUEnabled) return {}; cross_tu::CrossTranslationUnitContext &CTUCtx = *Engine->getCrossTranslationUnitContext(); llvm::Expected CTUDeclOrError = - CTUCtx.getCrossTUDefinition(FD, Opts.getCTUDir(), Opts.getCTUIndexName()); + CTUCtx.getCrossTUDefinition(FD, Opts.CTUDir, + Opts.CTUIndexName); if (!CTUDeclOrError) { handleAllErrors(CTUDeclOrError.takeError(), diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 49ddf1a..fa5a619 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -193,7 +193,7 @@ ExprEngine::ExprEngine(cross_tu::CrossTranslationUnitContext &CTU, svalBuilder(StateMgr.getSValBuilder()), ObjCNoRet(mgr.getASTContext()), BR(mgr, *this), VisitedCallees(VisitedCalleesIn), HowToInline(HowToInlineIn) { - unsigned TrimInterval = mgr.options.getGraphTrimInterval(); + unsigned TrimInterval = mgr.options.GraphTrimInterval; if (TrimInterval != 0) { // Enable eager node reclaimation when constructing the ExplodedGraph. G.enableNodeReclamation(TrimInterval); @@ -746,7 +746,7 @@ void ExprEngine::ProcessLoopExit(const Stmt* S, ExplodedNode *Pred) { NodeBuilder Bldr(Pred, Dst, *currBldrCtx); ProgramStateRef NewState = Pred->getState(); - if(AMgr.options.shouldUnrollLoops()) + if(AMgr.options.ShouldUnrollLoops) NewState = processLoopEnd(S, NewState); LoopExit PP(S, Pred->getLocationContext()); @@ -878,7 +878,7 @@ void ExprEngine::ProcessNewAllocator(const CXXNewExpr *NE, // TODO: We're not evaluating allocators for all cases just yet as // we're not handling the return value correctly, which causes false // positives when the alpha.cplusplus.NewDeleteLeaks check is on. - if (Opts.mayInlineCXXAllocator()) + if (Opts.MayInlineCXXAllocator) VisitCXXNewAllocatorCall(NE, Pred, Dst); else { NodeBuilder Bldr(Pred, Dst, *currBldrCtx); @@ -1093,7 +1093,7 @@ void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE, // This is a fallback solution in case we didn't have a construction // context when we were constructing the temporary. Otherwise the map should // have been populated there. - if (!getAnalysisManager().options.includeTemporaryDtorsInCFG()) { + if (!getAnalysisManager().options.ShouldIncludeTemporaryDtorsInCFG) { // In case we don't have temporary destructors in the CFG, do not mark // the initialization - we would otherwise never clean it up. Dst = PreVisit; @@ -1454,7 +1454,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, break; case Stmt::LambdaExprClass: - if (AMgr.options.shouldInlineLambdas()) { + if (AMgr.options.ShouldInlineLambdas) { Bldr.takeNodes(Pred); VisitLambdaExpr(cast(S), Pred, Dst); Bldr.addNodes(Dst); @@ -1483,7 +1483,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, Bldr.takeNodes(Pred); - if (AMgr.options.shouldEagerlyAssume() && + if (AMgr.options.ShouldEagerlyAssume && (B->isRelationalOp() || B->isEqualityOp())) { ExplodedNodeSet Tmp; VisitBinaryOperator(cast(S), Pred, Tmp); @@ -1747,7 +1747,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::UnaryOperatorClass: { Bldr.takeNodes(Pred); const auto *U = cast(S); - if (AMgr.options.shouldEagerlyAssume() && (U->getOpcode() == UO_LNot)) { + if (AMgr.options.ShouldEagerlyAssume && (U->getOpcode() == UO_LNot)) { ExplodedNodeSet Tmp; VisitUnaryOperator(U, Pred, Tmp); evalEagerlyAssumeBinOpBifurcation(Dst, Tmp, U); @@ -1848,7 +1848,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L, PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext()); // If we reach a loop which has a known bound (and meets // other constraints) then consider completely unrolling it. - if(AMgr.options.shouldUnrollLoops()) { + if(AMgr.options.ShouldUnrollLoops) { unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath; const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminator(); if (Term) { @@ -1870,7 +1870,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L, // maximum number of times, widen the loop. unsigned int BlockCount = nodeBuilder.getContext().blockCount(); if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 && - AMgr.options.shouldWidenLoops()) { + AMgr.options.ShouldWidenLoops) { const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminator(); if (!(Term && (isa(Term) || isa(Term) || isa(Term)))) @@ -2371,7 +2371,7 @@ void ExprEngine::VisitCommonDeclRefExpr(const Expr *Ex, const NamedDecl *D, const auto *DeclRefEx = dyn_cast(Ex); Optional> VInfo; - if (AMgr.options.shouldInlineLambdas() && DeclRefEx && + if (AMgr.options.ShouldInlineLambdas && DeclRefEx && DeclRefEx->refersToEnclosingVariableOrCapture() && MD && MD->getParent()->isLambda()) { // Lookup the field of the lambda. diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp index 01606d1..1f64976 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp @@ -159,7 +159,7 @@ std::pair ExprEngine::prepareForObjectConstruction( return std::make_pair(State, FieldVal); } case ConstructionContext::NewAllocatedObjectKind: { - if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) { + if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) { const auto *NECC = cast(CC); const auto *NE = NECC->getCXXNewExpr(); SVal V = *getObjectUnderConstruction(State, NE, LCtx); @@ -210,7 +210,7 @@ std::pair ExprEngine::prepareForObjectConstruction( llvm_unreachable("Unhandled return value construction context!"); } case ConstructionContext::ElidedTemporaryObjectKind: { - assert(AMgr.getAnalyzerOptions().shouldElideConstructors()); + assert(AMgr.getAnalyzerOptions().ShouldElideConstructors); const auto *TCC = cast(CC); const CXXBindTemporaryExpr *BTE = TCC->getCXXBindTemporaryExpr(); const MaterializeTemporaryExpr *MTE = TCC->getMaterializedTemporaryExpr(); @@ -706,7 +706,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, ProgramStateRef State = Pred->getState(); // Retrieve the stored operator new() return value. - if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) { + if (AMgr.getAnalyzerOptions().MayInlineCXXAllocator) { symVal = *getObjectUnderConstruction(State, CNE, LCtx); State = finishObjectConstruction(State, CNE, LCtx); } @@ -726,7 +726,7 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred, CallEventRef Call = CEMgr.getCXXAllocatorCall(CNE, State, LCtx); - if (!AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) { + if (!AMgr.getAnalyzerOptions().MayInlineCXXAllocator) { // Invalidate placement args. // FIXME: Once we figure out how we want allocators to work, // we should be using the usual pre-/(default-)eval-/post-call checks here. diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index 66cbeba..758195d 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp @@ -349,7 +349,7 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) { /*WasInlined=*/true); } else if (CE && !(isa(CE) && // Called when visiting CXXNewExpr. - AMgr.getAnalyzerOptions().mayInlineCXXAllocator())) { + AMgr.getAnalyzerOptions().MayInlineCXXAllocator)) { getCheckerManager().runCheckersForPostStmt(Dst, DstPostCall, CE, *this, /*WasInlined=*/true); } else { @@ -386,7 +386,7 @@ void ExprEngine::examineStackFrames(const Decl *D, const LocationContext *LCtx, // Do not count the small functions when determining the stack depth. AnalysisDeclContext *CalleeADC = AMgr.getAnalysisDeclContext(DI); const CFG *CalleeCFG = CalleeADC->getCFG(); - if (CalleeCFG->getNumBlockIDs() > AMgr.options.getAlwaysInlineSize()) + if (CalleeCFG->getNumBlockIDs() > AMgr.options.AlwaysInlineSize) ++StackDepth; } LCtx = LCtx->getParent(); @@ -683,7 +683,7 @@ ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred, : nullptr; if (CC && isa(CC) && - !Opts.mayInlineCXXAllocator()) + !Opts.MayInlineCXXAllocator) return CIP_DisallowedOnce; // FIXME: We don't handle constructors or destructors for arrays properly. @@ -712,7 +712,7 @@ ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred, // If we don't handle temporary destructors, we shouldn't inline // their constructors. if (CallOpts.IsTemporaryCtorOrDtor && - !Opts.includeTemporaryDtorsInCFG()) + !Opts.ShouldIncludeTemporaryDtorsInCFG) return CIP_DisallowedOnce; // If we did not find the correct this-region, it would be pointless @@ -743,7 +743,8 @@ ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred, return CIP_DisallowedOnce; // Allow disabling temporary destructor inlining with a separate option. - if (CallOpts.IsTemporaryCtorOrDtor && !Opts.mayInlineCXXTemporaryDtors()) + if (CallOpts.IsTemporaryCtorOrDtor && + !Opts.MayInlineCXXTemporaryDtors) return CIP_DisallowedOnce; // If we did not find the correct this-region, it would be pointless @@ -754,13 +755,13 @@ ExprEngine::mayInlineCallKind(const CallEvent &Call, const ExplodedNode *Pred, break; } case CE_CXXAllocator: - if (Opts.mayInlineCXXAllocator()) + if (Opts.MayInlineCXXAllocator) break; // Do not inline allocators until we model deallocators. // This is unfortunate, but basically necessary for smart pointers and such. return CIP_DisallowedAlways; case CE_ObjCMessage: - if (!Opts.mayInlineObjCMethod()) + if (!Opts.MayInlineObjCMethod) return CIP_DisallowedAlways; if (!(Opts.getIPAMode() == IPAK_DynamicDispatch || Opts.getIPAMode() == IPAK_DynamicDispatchBifurcate)) @@ -844,19 +845,19 @@ static bool mayInlineDecl(AnalysisManager &AMgr, if (Ctx.getLangOpts().CPlusPlus) { if (const FunctionDecl *FD = dyn_cast(CalleeADC->getDecl())) { // Conditionally control the inlining of template functions. - if (!Opts.mayInlineTemplateFunctions()) + if (!Opts.MayInlineTemplateFunctions) if (FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate) return false; // Conditionally control the inlining of C++ standard library functions. - if (!Opts.mayInlineCXXStandardLibrary()) + if (!Opts.MayInlineCXXStandardLibrary) if (Ctx.getSourceManager().isInSystemHeader(FD->getLocation())) if (AnalysisDeclContext::isInStdNamespace(FD)) return false; // Conditionally control the inlining of methods on objects that look // like C++ containers. - if (!Opts.mayInlineCXXContainerMethods()) + if (!Opts.MayInlineCXXContainerMethods) if (!AMgr.isInCodeFile(FD->getLocation())) if (isContainerMethod(Ctx, FD)) return false; @@ -865,7 +866,7 @@ static bool mayInlineDecl(AnalysisManager &AMgr, // We don't currently do a good job modeling shared_ptr because we can't // see the reference count, so treating as opaque is probably the best // idea. - if (!Opts.mayInlineCXXSharedPtrDtor()) + if (!Opts.MayInlineCXXSharedPtrDtor) if (isCXXSharedPtrDtor(FD)) return false; } @@ -878,7 +879,7 @@ static bool mayInlineDecl(AnalysisManager &AMgr, return false; // Do not inline large functions. - if (CalleeCFG->getNumBlockIDs() > Opts.getMaxInlinableSize()) + if (CalleeCFG->getNumBlockIDs() > Opts.MaxInlinableSize) return false; // It is possible that the live variables analysis cannot be @@ -946,21 +947,21 @@ bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D, unsigned StackDepth = 0; examineStackFrames(D, Pred->getLocationContext(), IsRecursive, StackDepth); if ((StackDepth >= Opts.InlineMaxStackDepth) && - ((CalleeCFG->getNumBlockIDs() > Opts.getAlwaysInlineSize()) + ((CalleeCFG->getNumBlockIDs() > Opts.AlwaysInlineSize) || IsRecursive)) return false; // Do not inline large functions too many times. if ((Engine.FunctionSummaries->getNumTimesInlined(D) > - Opts.getMaxTimesInlineLarge()) && + Opts.MaxTimesInlineLarge) && CalleeCFG->getNumBlockIDs() >= - Opts.getMinCFGSizeTreatFunctionsAsLarge()) { + Opts.MinCFGSizeTreatFunctionsAsLarge) { NumReachedInlineCountMax++; return false; } if (HowToInline == Inline_Minimal && - (CalleeCFG->getNumBlockIDs() > Opts.getAlwaysInlineSize() + (CalleeCFG->getNumBlockIDs() > Opts.AlwaysInlineSize || IsRecursive)) return false; diff --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp index d5764a4..fc82f11 100644 --- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp @@ -218,7 +218,7 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D, int FD; SmallString<128> Model, ResultPath; - if (!AnalyzerOpts.shouldWriteStableReportFilename()) { + if (!AnalyzerOpts.ShouldWriteStableReportFilename) { llvm::sys::path::append(Model, Directory, "report-%%%%%%.html"); if (std::error_code EC = llvm::sys::fs::make_absolute(Model)) { diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index 6ce4242..f1fabdd 100644 --- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -471,7 +471,7 @@ static void printBugPath(llvm::raw_ostream &o, const FIDMap& FM, o << " \n"; - if (!AnOpts.shouldDisplayMacroExpansions()) + if (!AnOpts.ShouldDisplayMacroExpansions) return; o << " macro_expansions\n" @@ -704,7 +704,7 @@ void PlistDiagnostics::FlushDiagnosticsImpl( EmitString(o << " ", SM.getFileEntryForID(FID)->getName()) << '\n'; o << " \n"; - if (llvm::AreStatisticsEnabled() && AnOpts.shouldSerializeStats()) { + if (llvm::AreStatisticsEnabled() && AnOpts.ShouldSerializeStats) { o << " statistics\n"; std::string stats; llvm::raw_string_ostream os(stats); diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 29b6058..f5eb9b5 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -350,7 +350,7 @@ public: if (SubEngine *Eng = StateMgr.getOwningEngine()) { AnalyzerOptions &Options = Eng->getAnalysisManager().options; SmallStructLimit = - Options.getRegionStoreSmallStructLimit(); + Options.RegionStoreSmallStructLimit; } } diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp index 8c39b79..617c4ba 100644 --- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -385,7 +385,7 @@ SVal SValBuilder::makeSymExprValNN(BinaryOperator::Opcode Op, // instead of generating an Unknown value and propagate the taint info to it. const unsigned MaxComp = StateMgr.getOwningEngine() ->getAnalysisManager() - .options.getMaxSymbolComplexity(); + .options.MaxSymbolComplexity; if (symLHS && symRHS && (symLHS->computeComplexity() + symRHS->computeComplexity()) < MaxComp) diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index 19d7125..2f6a0c8 100644 --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -459,7 +459,7 @@ static Optional tryRearrange(ProgramStateRef State, // FIXME: After putting complexity threshold to the symbols we can always // rearrange additive operations but rearrange comparisons only if // option is set. - if(!Opts.shouldAggressivelySimplifyBinaryOperation()) + if(!Opts.ShouldAggressivelySimplifyBinaryOperation) return None; SymbolRef LSym = Lhs.getAsSymbol(); diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp index 4324ed2d..d87937d 100644 --- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp @@ -204,7 +204,7 @@ public: PP(CI.getPreprocessor()), OutDir(outdir), Opts(std::move(opts)), Plugins(plugins), Injector(injector), CTU(CI) { DigestAnalyzerOptions(); - if (Opts->PrintStats || Opts->shouldSerializeStats()) { + if (Opts->PrintStats || Opts->ShouldSerializeStats) { AnalyzerTimers = llvm::make_unique( "analyzer", "Analyzer timers"); TUTotalTimer = llvm::make_unique( @@ -739,7 +739,7 @@ void AnalysisConsumer::RunPathSensitiveChecks(Decl *D, // Execute the worklist algorithm. Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D), - Mgr->options.getMaxNodesPerTopLevelFunction()); + Mgr->options.MaxNodesPerTopLevelFunction); if (!Mgr->options.DumpExplodedGraphTo.empty()) Eng.DumpGraph(Mgr->options.TrimGraph, Mgr->options.DumpExplodedGraphTo); diff --git a/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp b/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp index c0cf395e..b1927c8 100644 --- a/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp @@ -48,7 +48,7 @@ void ModelInjector::onBodySynthesis(const NamedDecl *D) { FileID mainFileID = SM.getMainFileID(); AnalyzerOptionsRef analyzerOpts = CI.getAnalyzerOpts(); - llvm::StringRef modelPath = analyzerOpts->getModelPath(); + llvm::StringRef modelPath = analyzerOpts->ModelPath; llvm::SmallString<128> fileName; diff --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c index 20e2fe5..96f1e00 100644 --- a/clang/test/Analysis/analyzer-config.c +++ b/clang/test/Analysis/analyzer-config.c @@ -1,16 +1,16 @@ // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core,osx.cocoa,debug.ConfigDumper -analyzer-max-loop 34 > %t 2>&1 // RUN: FileCheck --input-file=%t %s --match-full-lines -void bar() {} -void foo() { - // Call bar 33 times so max-times-inline-large is met and - // min-blocks-for-inline-large is checked - for (int i = 0; i < 34; ++i) { - bar(); - } -} - // CHECK: [config] +// CHECK-NEXT: aggressive-binary-operation-simplification = false +// CHECK-NEXT: avoid-suppressing-null-argument-paths = false +// CHECK-NEXT: c++-allocator-inlining = true +// CHECK-NEXT: c++-container-inlining = false +// CHECK-NEXT: c++-inlining = destructors +// CHECK-NEXT: c++-shared_ptr-inlining = false +// CHECK-NEXT: c++-stdlib-inlining = true +// CHECK-NEXT: c++-temp-dtor-inlining = true +// CHECK-NEXT: c++-template-inlining = true // CHECK-NEXT: cfg-conditional-static-initializers = true // CHECK-NEXT: cfg-implicit-dtors = true // CHECK-NEXT: cfg-lifetime = false @@ -18,8 +18,13 @@ void foo() { // CHECK-NEXT: cfg-rich-constructors = true // CHECK-NEXT: cfg-scopes = false // CHECK-NEXT: cfg-temporary-dtors = true +// CHECK-NEXT: crosscheck-with-z3 = false +// CHECK-NEXT: ctu-dir = "" +// CHECK-NEXT: ctu-index-name = externalFnMap.txt // CHECK-NEXT: eagerly-assume = true // CHECK-NEXT: elide-constructors = true +// CHECK-NEXT: expand-macros = false +// CHECK-NEXT: experimental-enable-naive-ctu-analysis = false // CHECK-NEXT: exploration_strategy = unexplored_first_queue // CHECK-NEXT: faux-bodies = true // CHECK-NEXT: graph-trim-interval = 1000 @@ -28,12 +33,22 @@ void foo() { // CHECK-NEXT: ipa-always-inline-size = 3 // CHECK-NEXT: max-inlinable-size = 100 // CHECK-NEXT: max-nodes = 225000 +// CHECK-NEXT: max-symbol-complexity = 35 // CHECK-NEXT: max-times-inline-large = 32 // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14 // CHECK-NEXT: mode = deep +// CHECK-NEXT: model-path = "" +// CHECK-NEXT: notes-as-events = false +// CHECK-NEXT: objc-inlining = true +// CHECK-NEXT: prune-paths = true // CHECK-NEXT: region-store-small-struct-limit = 2 +// CHECK-NEXT: report-in-main-source-file = false // CHECK-NEXT: serialize-stats = false +// CHECK-NEXT: stable-report-filename = false +// CHECK-NEXT: suppress-c++-stdlib = true +// CHECK-NEXT: suppress-inlined-defensive-checks = true +// CHECK-NEXT: suppress-null-return-paths = true // CHECK-NEXT: unroll-loops = false // CHECK-NEXT: widen-loops = false // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 24 +// CHECK-NEXT: num-entries = 48 diff --git a/clang/test/Analysis/analyzer-config.cpp b/clang/test/Analysis/analyzer-config.cpp index 2c8098e..501a7336 100644 --- a/clang/test/Analysis/analyzer-config.cpp +++ b/clang/test/Analysis/analyzer-config.cpp @@ -1,24 +1,10 @@ // RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core,osx.cocoa,debug.ConfigDumper -analyzer-max-loop 34 > %t 2>&1 // RUN: FileCheck --input-file=%t %s --match-full-lines -void bar() {} -void foo() { - // Call bar 33 times so max-times-inline-large is met and - // min-blocks-for-inline-large is checked - for (int i = 0; i < 34; ++i) { - bar(); - } -} - -class Foo { -public: - ~Foo() {} - void baz() { Foo(); } - void bar() { const Foo &f = Foo(); } - void foo() { bar(); } -}; - // CHECK: [config] +// CHECK-NEXT: aggressive-binary-operation-simplification = false +// CHECK-NEXT: avoid-suppressing-null-argument-paths = false +// CHECK-NEXT: c++-allocator-inlining = true // CHECK-NEXT: c++-container-inlining = false // CHECK-NEXT: c++-inlining = destructors // CHECK-NEXT: c++-shared_ptr-inlining = false @@ -32,8 +18,12 @@ public: // CHECK-NEXT: cfg-rich-constructors = true // CHECK-NEXT: cfg-scopes = false // CHECK-NEXT: cfg-temporary-dtors = true +// CHECK-NEXT: crosscheck-with-z3 = false +// CHECK-NEXT: ctu-dir = "" +// CHECK-NEXT: ctu-index-name = externalFnMap.txt // CHECK-NEXT: eagerly-assume = true // CHECK-NEXT: elide-constructors = true +// CHECK-NEXT:expand-macros = false // CHECK-NEXT: experimental-enable-naive-ctu-analysis = false // CHECK-NEXT: exploration_strategy = unexplored_first_queue // CHECK-NEXT: faux-bodies = true @@ -43,12 +33,22 @@ public: // CHECK-NEXT: ipa-always-inline-size = 3 // CHECK-NEXT: max-inlinable-size = 100 // CHECK-NEXT: max-nodes = 225000 +// CHECK-NEXT: max-symbol-complexity = 35 // CHECK-NEXT: max-times-inline-large = 32 // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14 // CHECK-NEXT: mode = deep +// CHECK-NEXT: model-path = "" +// CHECK-NEXT: notes-as-events = false +// CHECK-NEXT: objc-inlining = true +// CHECK-NEXT: prune-paths = true // CHECK-NEXT: region-store-small-struct-limit = 2 +// CHECK-NEXT: report-in-main-source-file = false // CHECK-NEXT: serialize-stats = false +// CHECK-NEXT: stable-report-filename = false +// CHECK-NEXT: suppress-c++-stdlib = true +// CHECK-NEXT: suppress-inlined-defensive-checks = true +// CHECK-NEXT: suppress-null-return-paths = true // CHECK-NEXT: unroll-loops = false // CHECK-NEXT: widen-loops = false // CHECK-NEXT: [stats] -// CHECK-NEXT: num-entries = 31 +// CHECK-NEXT: num-entries = 48 -- 2.7.4