17 #include "llvm/ADT/SmallString.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/Support/ErrorHandling.h" 20 #include "llvm/Support/raw_ostream.h" 22 using namespace clang;
26 std::vector<StringRef>
28 static const StringRef StaticAnalyzerChecks[] = {
30 #define CHECKER(FULLNAME, CLASS, DESCFILE, HELPTEXT, GROUPINDEX, HIDDEN) \ 32 #include "clang/StaticAnalyzer/Checkers/Checkers.inc" 36 std::vector<StringRef> Result;
37 for (StringRef
CheckName : StaticAnalyzerChecks) {
39 (IncludeExperimental || !
CheckName.startswith(
"alpha.")))
46 if (UserMode == UMK_NotSet) {
48 Config.insert(std::make_pair(
"mode",
"deep")).first->second;
49 UserMode = llvm::StringSwitch<UserModeKind>(ModeStr)
50 .Case(
"shallow", UMK_Shallow)
51 .Case(
"deep", UMK_Deep)
53 assert(UserMode != UMK_NotSet &&
"User mode is invalid.");
64 const char *DefaultIPA =
nullptr;
65 UserModeKind HighLevelMode = getUserMode();
66 if (HighLevelMode == UMK_Shallow)
67 DefaultIPA =
"inlining";
68 else if (HighLevelMode == UMK_Deep)
69 DefaultIPA =
"dynamic-bifurcate";
74 Config.insert(std::make_pair(
"ipa", DefaultIPA)).first->second;
75 IPAKind IPAConfig = llvm::StringSwitch<IPAKind>(ModeStr)
82 assert(IPAConfig !=
IPAK_NotSet &&
"IPA Mode is invalid.");
96 if (!CXXMemberInliningMode) {
97 static const char *ModeKey =
"c++-inlining";
100 Config.insert(std::make_pair(ModeKey,
"destructors")).first->second;
105 MutableMode = llvm::StringSwitch<CXXInlineableMemberKind>(ModeStr)
119 return CXXMemberInliningMode >= K;
122 static StringRef
toString(
bool b) {
return b ?
"true" :
"false"; }
124 StringRef AnalyzerOptions::getCheckerOption(StringRef CheckerName,
125 StringRef OptionName,
127 bool SearchInParents) {
130 ConfigTable::const_iterator E = Config.end();
132 ConfigTable::const_iterator I =
133 Config.find((Twine(CheckerName) +
":" + OptionName).str());
135 return StringRef(I->getValue());
136 size_t Pos = CheckerName.rfind(
'.');
137 if (Pos == StringRef::npos)
139 CheckerName = CheckerName.substr(0, Pos);
140 }
while (!CheckerName.empty() && SearchInParents);
146 bool SearchInParents) {
154 : StringRef(Config.insert(std::make_pair(Name, Default)).first->second);
155 return llvm::StringSwitch<bool>(V)
157 .Case(
"false",
false)
158 .Default(DefaultVal);
163 bool SearchInParents) {
165 V = getBooleanOption(Name, DefaultVal, C, SearchInParents);
170 return getBooleanOption(IncludeTemporaryDtorsInCFG,
171 "cfg-temporary-dtors",
176 return getBooleanOption(IncludeImplicitDtorsInCFG,
177 "cfg-implicit-dtors",
182 return getBooleanOption(IncludeLifetimeInCFG,
"cfg-lifetime",
187 return getBooleanOption(IncludeLoopExitInCFG,
"cfg-loopexit",
192 return getBooleanOption(InlineCXXStandardLibrary,
193 "c++-stdlib-inlining",
198 return getBooleanOption(InlineTemplateFunctions,
199 "c++-template-inlining",
204 return getBooleanOption(InlineCXXAllocator,
205 "c++-allocator-inlining",
210 return getBooleanOption(InlineCXXContainerMethods,
211 "c++-container-inlining",
216 return getBooleanOption(InlineCXXSharedPtrDtor,
217 "c++-shared_ptr-inlining",
223 return getBooleanOption(ObjCInliningMode,
229 return getBooleanOption(SuppressNullReturnPaths,
230 "suppress-null-return-paths",
235 return getBooleanOption(AvoidSuppressingNullArgumentPaths,
236 "avoid-suppressing-null-argument-paths",
241 return getBooleanOption(SuppressInlinedDefensiveChecks,
242 "suppress-inlined-defensive-checks",
247 return getBooleanOption(SuppressFromCXXStandardLibrary,
248 "suppress-c++-stdlib",
253 return getBooleanOption(ReportIssuesInMainSourceFile,
254 "report-in-main-source-file",
260 return getBooleanOption(StableReportFilename,
261 "stable-report-filename",
267 bool SearchInParents) {
269 llvm::raw_svector_ostream OS(StrBuf);
274 : StringRef(Config.insert(std::make_pair(Name, OS.str()))
277 int Res = DefaultVal;
278 bool b = V.getAsInteger(10, Res);
279 assert(!b &&
"analyzer-config option should be numeric");
285 StringRef DefaultVal,
287 bool SearchInParents) {
291 Config.insert(std::make_pair(Name, DefaultVal)).first->second);
295 if (!AlwaysInlineSize.hasValue())
296 AlwaysInlineSize = getOptionAsInteger(
"ipa-always-inline-size", 3);
297 return AlwaysInlineSize.getValue();
301 if (!MaxInlinableSize.hasValue()) {
303 int DefaultValue = 0;
304 UserModeKind HighLevelMode = getUserMode();
305 switch (HighLevelMode) {
307 llvm_unreachable(
"Invalid mode.");
316 MaxInlinableSize = getOptionAsInteger(
"max-inlinable-size", DefaultValue);
318 return MaxInlinableSize.getValue();
322 if (!GraphTrimInterval.hasValue())
323 GraphTrimInterval = getOptionAsInteger(
"graph-trim-interval", 1000);
324 return GraphTrimInterval.getValue();
328 if (!MaxTimesInlineLarge.hasValue())
329 MaxTimesInlineLarge = getOptionAsInteger(
"max-times-inline-large", 32);
330 return MaxTimesInlineLarge.getValue();
334 if (!MinCFGSizeTreatFunctionsAsLarge.hasValue())
335 MinCFGSizeTreatFunctionsAsLarge = getOptionAsInteger(
336 "min-cfg-size-treat-functions-as-large", 14);
337 return MinCFGSizeTreatFunctionsAsLarge.getValue();
341 if (!MaxNodesPerTopLevelFunction.hasValue()) {
342 int DefaultValue = 0;
343 UserModeKind HighLevelMode = getUserMode();
344 switch (HighLevelMode) {
346 llvm_unreachable(
"Invalid mode.");
348 DefaultValue = 75000;
351 DefaultValue = 225000;
354 MaxNodesPerTopLevelFunction = getOptionAsInteger(
"max-nodes", DefaultValue);
356 return MaxNodesPerTopLevelFunction.getValue();
360 return getBooleanOption(
"faux-bodies",
true);
364 return getBooleanOption(
"prune-paths",
true);
368 return getBooleanOption(
"cfg-conditional-static-initializers",
true);
372 if (!InlineLambdas.hasValue())
373 InlineLambdas = getBooleanOption(
"inline-lambdas",
true);
374 return InlineLambdas.getValue();
378 if (!WidenLoops.hasValue())
379 WidenLoops = getBooleanOption(
"widen-loops",
false);
380 return WidenLoops.getValue();
384 if (!UnrollLoops.hasValue())
385 UnrollLoops = getBooleanOption(
"unroll-loops",
false);
386 return UnrollLoops.getValue();
390 if (!DisplayNotesAsEvents.hasValue())
391 DisplayNotesAsEvents =
392 getBooleanOption(
"notes-as-events",
false);
393 return DisplayNotesAsEvents.getValue();
Inline C functions and blocks when their definitions are available.
bool shouldDisplayNotesAsEvents()
Returns true if the bug reporter should transparently treat extra note diagnostic pieces as event dia...
IPAKind
Describes the different modes of inter-procedural analysis.
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
bool shouldSuppressNullReturnPaths()
Returns whether or not paths that go through null returns should be suppressed.
bool shouldPrunePaths()
Returns whether irrelevant parts of a bug report path should be pruned out of the final output...
bool shouldAvoidSuppressingNullArgumentPaths()
Returns whether a bug report should not be suppressed if its path includes a call with a null argumen...
bool shouldWidenLoops()
Returns true if the analysis should try to widen loops.
Perform only intra-procedural analysis.
A dummy mode in which no C++ inlining is enabled.
bool mayInlineTemplateFunctions()
Returns whether or not templated functions may be considered for inlining.
Inline callees(C, C++, ObjC) when their definitions are available.
StringRef getOptionAsString(StringRef Name, StringRef DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Query an option's string value.
bool includeLoopExitInCFG()
Returns whether or not the end of the loop information should be included in the CFG.
StringRef getTagDescription() const override
bool mayInlineCXXContainerMethods()
Returns whether or not methods of C++ container objects may be considered for inlining.
static std::vector< StringRef > getRegisteredCheckers(bool IncludeExperimental=false)
bool includeLifetimeInCFG()
Returns whether or not end-of-lifetime information should be included in the CFG. ...
unsigned getMinCFGSizeTreatFunctionsAsLarge()
Returns the number of basic blocks a function needs to have to be considered large for the 'max-times...
bool shouldUnrollLoops()
Returns true if the analysis should try to unroll loops with known bounds.
unsigned getMaxInlinableSize()
UserModeKind getUserMode()
Retrieves and sets the UserMode.
bool shouldSuppressInlinedDefensiveChecks()
Returns whether or not diagnostics containing inlined defensive NULL checks should be suppressed...
bool shouldWriteStableReportFilename()
Returns whether or not the report filename should be random or not.
IPAKind getIPAMode()
Returns the inter-procedural analysis mode.
Refers to regular member function and operator calls.
bool mayInlineObjCMethod()
Returns true if ObjectiveC inlining is enabled, false otherwise.
bool shouldConditionalizeStaticInitializers()
Returns true if 'static' initializers should be in conditional logic in the CFG.
Refers to constructors (implicit or explicit).
Enable inlining of dynamically dispatched methods.
bool getBooleanOption(StringRef Name, bool DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Interprets an option's string value as a boolean.
unsigned getAlwaysInlineSize()
unsigned getMaxNodesPerTopLevelFunction()
Returns the maximum number of nodes the analyzer can generate while exploring a top level function (f...
bool mayInlineCXXStandardLibrary()
Returns whether or not C++ standard library functions may be considered for inlining.
Refers to destructors (implicit or explicit).
Dataflow Directional Tag Classes.
unsigned getGraphTrimInterval()
Returns how often nodes in the ExplodedGraph should be recycled to save memory.
bool includeTemporaryDtorsInCFG()
Returns whether or not the destructors for C++ temporary objects should be included in the CFG...
bool shouldSuppressFromCXXStandardLibrary()
Returns whether or not diagnostics reported within the C++ standard library should be suppressed...
bool includeImplicitDtorsInCFG()
Returns whether or not implicit destructors for C++ objects should be included in the CFG...
bool shouldSynthesizeBodies()
Returns true if the analyzer engine should synthesize fake bodies for well-known functions.
bool mayInlineCXXMemberFunction(CXXInlineableMemberKind K)
Returns the option controlling which C++ member functions will be considered for inlining.
unsigned getMaxTimesInlineLarge()
Returns the maximum times a large function could be inlined.
CXXInlineableMemberKind
Describes the different kinds of C++ member functions which can be considered for inlining by the ana...
int getOptionAsInteger(StringRef Name, int DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Interprets an option's string value as an integer value.
bool mayInlineCXXAllocator()
Returns whether or not allocator call may be considered for inlining.
Enable inlining of dynamically dispatched methods, bifurcate paths when exact type info is unavailabl...
bool mayInlineCXXSharedPtrDtor()
Returns whether or not the destructor of C++ 'shared_ptr' may be considered for inlining.
bool shouldReportIssuesInMainSourceFile()
Returns whether or not the diagnostic report should be always reported in the main source file and no...
bool shouldInlineLambdas()
Returns true if lambdas should be inlined.
static StringRef toString(bool b)