diff --git a/clang/include/clang/Checker/PathSensitive/AnalysisManager.h b/clang/include/clang/Checker/PathSensitive/AnalysisManager.h index 9194f4589908..3c7cb68c0943 100644 --- a/clang/include/clang/Checker/PathSensitive/AnalysisManager.h +++ b/clang/include/clang/Checker/PathSensitive/AnalysisManager.h @@ -37,8 +37,12 @@ class AnalysisManager : public BugReporterData { enum AnalysisScope { ScopeTU, ScopeDecl } AScope; + // The maximum number of exploded nodes the analyzer will generate. unsigned MaxNodes; + // The maximum number of times the analyzer will go through a loop. + unsigned MaxLoop; + bool VisualizeEGDot; bool VisualizeEGUbi; bool PurgeDead; @@ -59,12 +63,13 @@ public: const LangOptions &lang, PathDiagnosticClient *pd, StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, unsigned maxnodes, + unsigned maxloop, bool vizdot, bool vizubi, bool purge, bool eager, bool trim, bool inlinecall) : Ctx(ctx), Diags(diags), LangInfo(lang), PD(pd), CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), - AScope(ScopeDecl), MaxNodes(maxnodes), + AScope(ScopeDecl), MaxNodes(maxnodes), MaxLoop(maxloop), VisualizeEGDot(vizdot), VisualizeEGUbi(vizubi), PurgeDead(purge), EagerlyAssume(eager), TrimGraph(trim), InlineCall(inlinecall) {} @@ -110,6 +115,8 @@ public: unsigned getMaxNodes() const { return MaxNodes; } + unsigned getMaxLoop() const { return MaxLoop; } + bool shouldVisualizeGraphviz() const { return VisualizeEGDot; } bool shouldVisualizeUbigraph() const { return VisualizeEGUbi; } diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index b30663a1b633..d6932701cda0 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -99,6 +99,8 @@ def analyzer_inline_call : Flag<"-analyzer-inline-call">, HelpText<"Experimental transfer function inlining callees when its definition is available.">; def analyzer_max_nodes : Separate<"-analyzer-max-nodes">, HelpText<"The maximum number of nodes the analyzer can generate">; +def analyzer_max_loop : Separate<"-analyzer-max-loop">, + HelpText<"The maximum number of times the analyzer will go through a loop">; //===----------------------------------------------------------------------===// // CodeGen Options diff --git a/clang/include/clang/Frontend/AnalysisConsumer.h b/clang/include/clang/Frontend/AnalysisConsumer.h index 5dd80142eedb..2cbdf368a893 100644 --- a/clang/include/clang/Frontend/AnalysisConsumer.h +++ b/clang/include/clang/Frontend/AnalysisConsumer.h @@ -61,6 +61,7 @@ public: AnalysisDiagClients AnalysisDiagOpt; std::string AnalyzeSpecificFunction; unsigned MaxNodes; + unsigned MaxLoop; unsigned AnalyzeAll : 1; unsigned AnalyzerDisplayProgress : 1; unsigned AnalyzeNestedBlocks : 1; diff --git a/clang/lib/Checker/GRExprEngine.cpp b/clang/lib/Checker/GRExprEngine.cpp index e9f42b46400f..24176586728c 100644 --- a/clang/lib/Checker/GRExprEngine.cpp +++ b/clang/lib/Checker/GRExprEngine.cpp @@ -1017,9 +1017,8 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred, bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred, GRBlockCounter BC) { - return BC.getNumVisited(Pred->getLocationContext()->getCurrentStackFrame(), - B->getBlockID()) < 3; + B->getBlockID()) < AMgr.getMaxLoop(); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Frontend/AnalysisConsumer.cpp b/clang/lib/Frontend/AnalysisConsumer.cpp index df74eadaa0a4..6a4727929e7a 100644 --- a/clang/lib/Frontend/AnalysisConsumer.cpp +++ b/clang/lib/Frontend/AnalysisConsumer.cpp @@ -174,7 +174,7 @@ public: Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(), PP.getLangOptions(), PD, CreateStoreMgr, CreateConstraintMgr, - Opts.MaxNodes, + Opts.MaxNodes, Opts.MaxLoop, Opts.VisualizeEGDot, Opts.VisualizeEGUbi, Opts.PurgeDead, Opts.EagerlyAssume, Opts.TrimGraph, Opts.InlineCall)); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index dca607e3cb5e..65d2f06c6c62 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -798,6 +798,7 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, Args.hasArg(OPT_analyzer_experimental_internal_checks); Opts.TrimGraph = Args.hasArg(OPT_trim_egraph); Opts.MaxNodes = getLastArgIntValue(Args, OPT_analyzer_max_nodes,150000,Diags); + Opts.MaxLoop = getLastArgIntValue(Args, OPT_analyzer_max_loop, 3, Diags); Opts.InlineCall = Args.hasArg(OPT_analyzer_inline_call); }