aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Driver/CC1Options.td2
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h13
-rw-r--r--lib/Frontend/CompilerInvocation.cpp1
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp41
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp2
-rw-r--r--test/Analysis/analyzer-config.c3
-rw-r--r--test/Analysis/analyzer-config.cpp3
7 files changed, 53 insertions, 12 deletions
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index fa3e56fe75..f84f177197 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -88,8 +88,6 @@ def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias<
def analyzer_disable_retry_exhausted : Flag<["-"], "analyzer-disable-retry-exhausted">,
HelpText<"Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)">;
-def analyzer_max_nodes : Separate<["-"], "analyzer-max-nodes">,
- HelpText<"The maximum number of nodes the analyzer can generate (150000 default, 0 = no limit)">;
def analyzer_max_loop : Separate<["-"], "analyzer-max-loop">,
HelpText<"The maximum number of times the analyzer will go through a loop">;
def analyzer_stats : Flag<["-"], "analyzer-stats">,
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 9b9749df98..e1fe082049 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -132,9 +132,6 @@ public:
std::string AnalyzeSpecificFunction;
- /// \brief The maximum number of exploded nodes the analyzer will generate.
- unsigned MaxNodes;
-
/// \brief The maximum number of times the analyzer visits a block.
unsigned maxBlockVisitOnPath;
@@ -223,6 +220,9 @@ private:
/// \sa getMaxTimesInlineLarge
llvm::Optional<unsigned> MaxTimesInlineLarge;
+ /// \sa getMaxNodesPerTopLevelFunction
+ llvm::Optional<unsigned> MaxNodesPerTopLevelFunction;
+
/// Interprets an option's string value as a boolean.
///
/// Accepts the strings "true" and "false".
@@ -332,6 +332,13 @@ public:
/// This is controlled by the 'max-times-inline-large' config option.
unsigned getMaxTimesInlineLarge();
+ /// Returns the maximum number of nodes the analyzer can generate while
+ /// exploring a top level function (for each exploded graph).
+ /// 150000 is default; 0 means no limit.
+ ///
+ /// This is controlled by the 'max-nodes' config option.
+ unsigned getMaxNodesPerTopLevelFunction();
+
public:
AnalyzerOptions() :
AnalysisStoreOpt(RegionStoreModel),
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index ae240577d1..a2b28bc539 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -218,7 +218,6 @@ static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
Opts.AnalyzeSpecificFunction = Args.getLastArgValue(OPT_analyze_function);
Opts.UnoptimizedCFG = Args.hasArg(OPT_analysis_UnoptimizedCFG);
Opts.TrimGraph = Args.hasArg(OPT_trim_egraph);
- Opts.MaxNodes = Args.getLastArgIntValue(OPT_analyzer_max_nodes, 150000,Diags);
Opts.maxBlockVisitOnPath = Args.getLastArgIntValue(OPT_analyzer_max_loop, 4, Diags);
Opts.PrintStats = Args.hasArg(OPT_analyzer_stats);
Opts.InlineMaxStackDepth =
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index d90b48d998..cb02e94d60 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -15,6 +15,7 @@
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -41,7 +42,7 @@ IPAKind AnalyzerOptions::getIPAMode() {
const char *DefaultIPA = 0;
UserModeKind HighLevelMode = getUserMode();
if (HighLevelMode == UMK_Shallow)
- DefaultIPA = "basic-inlining";
+ DefaultIPA = "inlining";
else if (HighLevelMode == UMK_Deep)
DefaultIPA = "dynamic-bifurcate";
assert(DefaultIPA);
@@ -172,8 +173,23 @@ unsigned AnalyzerOptions::getAlwaysInlineSize() {
}
unsigned AnalyzerOptions::getMaxInlinableSize() {
- if (!MaxInlinableSize.hasValue())
- MaxInlinableSize = getOptionAsInteger("max-inlinable-size", 50);
+ if (!MaxInlinableSize.hasValue()) {
+
+ int DefaultValue = 0;
+ UserModeKind HighLevelMode = getUserMode();
+ switch (HighLevelMode) {
+ default:
+ llvm_unreachable("Invalid mode.");
+ case UMK_Shallow:
+ DefaultValue = 4;
+ break;
+ case UMK_Deep:
+ DefaultValue = 50;
+ break;
+ }
+
+ MaxInlinableSize = getOptionAsInteger("max-inlinable-size", DefaultValue);
+ }
return MaxInlinableSize.getValue();
}
@@ -189,6 +205,25 @@ unsigned AnalyzerOptions::getMaxTimesInlineLarge() {
return MaxTimesInlineLarge.getValue();
}
+unsigned AnalyzerOptions::getMaxNodesPerTopLevelFunction() {
+ if (!MaxNodesPerTopLevelFunction.hasValue()) {
+ int DefaultValue = 0;
+ UserModeKind HighLevelMode = getUserMode();
+ switch (HighLevelMode) {
+ default:
+ llvm_unreachable("Invalid mode.");
+ case UMK_Shallow:
+ DefaultValue = 75000;
+ break;
+ case UMK_Deep:
+ DefaultValue = 150000;
+ break;
+ }
+ MaxNodesPerTopLevelFunction = getOptionAsInteger("max-nodes", DefaultValue);
+ }
+ return MaxNodesPerTopLevelFunction.getValue();
+}
+
bool AnalyzerOptions::shouldSynthesizeBodies() {
return getBooleanOption("faux-bodies", true);
}
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index c2c5256d9c..a319530552 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -616,7 +616,7 @@ void AnalysisConsumer::ActionExprEngine(Decl *D, bool ObjCGCEnabled,
// Execute the worklist algorithm.
Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
- Mgr->options.MaxNodes);
+ Mgr->options.getMaxNodesPerTopLevelFunction());
// Release the auditor (if any) so that it doesn't monitor the graph
// created BugReporter.
diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c
index 9d99b0a425..7fa299b786 100644
--- a/test/Analysis/analyzer-config.c
+++ b/test/Analysis/analyzer-config.c
@@ -11,7 +11,8 @@ void foo() { bar(); }
// CHECK-NEXT: ipa = dynamic-bifurcate
// CHECK-NEXT: ipa-always-inline-size = 3
// CHECK-NEXT: max-inlinable-size = 50
+// CHECK-NEXT: max-nodes = 150000
// CHECK-NEXT: max-times-inline-large = 32
// CHECK-NEXT: mode = deep
// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 8
+// CHECK-NEXT: num-entries = 9
diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp
index dafc86fe86..52700176b2 100644
--- a/test/Analysis/analyzer-config.cpp
+++ b/test/Analysis/analyzer-config.cpp
@@ -20,7 +20,8 @@ public:
// CHECK-NEXT: ipa = dynamic-bifurcate
// CHECK-NEXT: ipa-always-inline-size = 3
// CHECK-NEXT: max-inlinable-size = 50
+// CHECK-NEXT: max-nodes = 150000
// CHECK-NEXT: max-times-inline-large = 32
// CHECK-NEXT: mode = deep
// CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 11
+// CHECK-NEXT: num-entries = 12