Index: lib/StaticAnalyzer/Core/AnalyzerOptions.cpp =================================================================== --- lib/StaticAnalyzer/Core/AnalyzerOptions.cpp +++ lib/StaticAnalyzer/Core/AnalyzerOptions.cpp @@ -184,8 +184,10 @@ } bool AnalyzerOptions::includeLoopExitInCFG() { - return getBooleanOption(IncludeLoopExitInCFG, "cfg-loopexit", - /* Default = */ false); + bool explicitlyIncludeLoopExit = getBooleanOption(IncludeLoopExitInCFG, + "cfg-loopexit", + /* Default = */ false); + return shouldUnrollLoops() || explicitlyIncludeLoopExit; } bool AnalyzerOptions::mayInlineCXXStandardLibrary() { Index: lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1527,8 +1527,11 @@ if (Term) { ProgramStateRef NewState = updateLoopStack(Term, AMgr.getASTContext(), Pred); - if (NewState != Pred->getState()){ - Pred = nodeBuilder.generateNode(NewState, Pred); + if (NewState != Pred->getState()) { + ExplodedNode *UpdatedNode = nodeBuilder.generateNode(NewState, Pred); + if (!UpdatedNode) + return; + Pred = UpdatedNode; } } // Is we are inside an unrolled loop then no need the check the counters. Index: lib/StaticAnalyzer/Core/LoopUnrolling.cpp =================================================================== --- lib/StaticAnalyzer/Core/LoopUnrolling.cpp +++ lib/StaticAnalyzer/Core/LoopUnrolling.cpp @@ -13,15 +13,11 @@ /// //===----------------------------------------------------------------------===// -#include "clang/Analysis/CFGStmtMap.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/AST/ParentMap.h" -#include "clang/AST/StmtVisitor.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h" -#include "llvm/ADT/Statistic.h" using namespace clang; using namespace ento; @@ -72,11 +68,8 @@ ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State) { auto LS = State->get(); - assert(!LS.isEmpty() && "Loop not added to the stack."); - assert(LoopStmt == LS.getHead().getLoopStmt() && - "Loop is not on top of the stack."); - - State = State->set(LS.getTail()); + if (!LS.isEmpty() && LS.getHead().getLoopStmt() == LoopStmt) + State = State->set(LS.getTail()); return State; } Index: test/Analysis/loop-unrolling.cpp =================================================================== --- test/Analysis/loop-unrolling.cpp +++ test/Analysis/loop-unrolling.cpp @@ -272,3 +272,10 @@ int a = 22 / k; return 0; } + +int loopexit_while_empty_loopstack() { + if (getNum()) + for (int i = 1; i < 8; i++) + ; + return 0; +}