Index: lib/StaticAnalyzer/Core/LoopUnrolling.cpp =================================================================== --- lib/StaticAnalyzer/Core/LoopUnrolling.cpp +++ lib/StaticAnalyzer/Core/LoopUnrolling.cpp @@ -210,6 +210,29 @@ return !isPossiblyEscaped(CounterVar->getCanonicalDecl(), Pred); } +bool madeBranch(ExplodedNode* N, const Stmt* LoopStmt) { + while(PathDiagnosticLocation::getStmt(N) == LoopStmt) + N = N->getFirstPred(); + + while (!N->pred_empty()) + { + const Stmt* S = nullptr; + ProgramPoint P = N->getLocation(); + if (Optional BE = P.getAs()) + S = BE->getSrc()->getTerminator(); + + if (N->succ_size() > 1) + return true; + + if (S == LoopStmt) + return false; + + N = N->getFirstPred(); + } + + llvm_unreachable("Reached root without encountering the previous step"); +} + ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx, ExplodedNode* Pred) { auto State = Pred->getState(); @@ -220,8 +243,13 @@ auto LS = State->get(); if (!LS.isEmpty() && LoopStmt == LS.getHead().getLoopStmt() && - LCtx == LS.getHead().getLocationContext()) + LCtx == LS.getHead().getLocationContext()) { + if (LS.getHead().isUnrolled() && madeBranch(Pred, LoopStmt)) { + State = State->set(LS.getTail()); + State = State->add(LoopState::getNormal(LoopStmt, LCtx)); + } return State; + } if (!shouldCompletelyUnroll(LoopStmt, ASTCtx, Pred)) { State = State->add(LoopState::getNormal(LoopStmt, LCtx));