diff options
| author | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:49:54 +0900 |
|---|---|---|
| committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2025-01-09 18:49:54 +0900 |
| commit | e2810c9a248f4c7fbfae84bb32b6f7e01027458b (patch) | |
| tree | ae0b02a8491b969a1cee94ea16ffe42c559143c5 /clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | |
| parent | fa04eb4af95c1ca7377279728cb004bcd2324d01 (diff) | |
| parent | bdcf47e4bcb92889665825654bb80a8bbe30379e (diff) | |
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/single/switchusers/chapuni/cov/single/switch
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/CoreEngine.cpp')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/CoreEngine.cpp | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp index 67b7d30853d9..775a22e18c61 100644 --- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp @@ -444,7 +444,8 @@ void CoreEngine::HandleBranch(const Stmt *Cond, const Stmt *Term, NodeBuilderContext Ctx(*this, B, Pred); ExplodedNodeSet Dst; ExprEng.processBranch(Cond, Ctx, Pred, Dst, *(B->succ_begin()), - *(B->succ_begin() + 1)); + *(B->succ_begin() + 1), + getCompletedIterationCount(B, Pred)); // Enqueue the new frontier onto the worklist. enqueue(Dst); } @@ -591,6 +592,30 @@ ExplodedNode *CoreEngine::generateCallExitBeginNode(ExplodedNode *N, return isNew ? Node : nullptr; } +std::optional<unsigned> +CoreEngine::getCompletedIterationCount(const CFGBlock *B, + ExplodedNode *Pred) const { + const LocationContext *LC = Pred->getLocationContext(); + BlockCounter Counter = WList->getBlockCounter(); + unsigned BlockCount = + Counter.getNumVisited(LC->getStackFrame(), B->getBlockID()); + + const Stmt *Term = B->getTerminatorStmt(); + if (isa<ForStmt, WhileStmt, CXXForRangeStmt>(Term)) { + assert(BlockCount >= 1 && + "Block count of currently analyzed block must be >= 1"); + return BlockCount - 1; + } + if (isa<DoStmt>(Term)) { + // In a do-while loop one iteration happens before the first evaluation of + // the loop condition, so we don't subtract one. + return BlockCount; + } + // ObjCForCollectionStmt is skipped intentionally because the current + // application of the iteration counts is not relevant for it. + return std::nullopt; +} + void CoreEngine::enqueue(ExplodedNodeSet &Set) { for (const auto I : Set) WList->enqueue(I); |
