summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index eee5400fe17..2970a6c8794 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -17,6 +17,7 @@
#include "PrettyStackTraceLocationContext.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/ParentMap.h"
+#include "clang/Analysis/CFGStmtMap.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/Basic/Builtins.h"
@@ -27,6 +28,7 @@
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
@@ -1497,6 +1499,26 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
NodeBuilderWithSinks &nodeBuilder,
ExplodedNode *Pred) {
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()) {
+ const CFGBlock *ActualBlock = nodeBuilder.getContext().getBlock();
+ const Stmt *Term = ActualBlock->getTerminator();
+ if (Term && shouldCompletelyUnroll(Term, AMgr.getASTContext())) {
+ ProgramStateRef UnrolledState = markLoopAsUnrolled(
+ Term, Pred->getState(),
+ cast<FunctionDecl>(Pred->getStackFrame()->getDecl()));
+ if (UnrolledState != Pred->getState())
+ nodeBuilder.generateNode(UnrolledState, Pred);
+ return;
+ }
+
+ if (ActualBlock->empty())
+ return;
+
+ if (isUnrolledLoopBlock(ActualBlock, Pred, AMgr))
+ return;
+ }
// If this block is terminated by a loop and it has already been visited the
// maximum number of times, widen the loop.
OpenPOWER on IntegriCloud