summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAdam Balogh <adam.balogh@ericsson.com>2018-07-30 08:52:21 +0000
committerAdam Balogh <adam.balogh@ericsson.com>2018-07-30 08:52:21 +0000
commita692120cb76b25d1a683f7479b7549b455015951 (patch)
treeb48f122a39321bd6467623fbb571f23c714fbc08 /clang/lib
parent8b6eff4e77f07f2afd738a97a821b5d292b9fdf1 (diff)
downloadbcm5719-llvm-a692120cb76b25d1a683f7479b7549b455015951.tar.gz
bcm5719-llvm-a692120cb76b25d1a683f7479b7549b455015951.zip
[Analyzer] Iterator Checker Hotfix: Defer deletion of container data until its last iterator is cleaned up
The analyzer may consider a container region as dead while it still has live iterators. We must defer deletion of the data belonging to such containers until all its iterators are dead as well to be able to compare the iterator to the begin and the end of the container which is stored in the container data. Differential Revision: https://reviews.llvm.org/D48427 llvm-svn: 338234
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
index 56c250cd167..fc713bc4999 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
@@ -291,6 +291,7 @@ const ContainerData *getContainerData(ProgramStateRef State,
const MemRegion *Cont);
ProgramStateRef setContainerData(ProgramStateRef State, const MemRegion *Cont,
const ContainerData &CData);
+bool hasLiveIterators(ProgramStateRef State, const MemRegion *Cont);
bool isOutOfRange(ProgramStateRef State, const IteratorPosition &Pos);
bool isZero(ProgramStateRef State, const NonLoc &Val);
} // namespace
@@ -536,7 +537,11 @@ void IteratorChecker::checkDeadSymbols(SymbolReaper &SR,
auto ContMap = State->get<ContainerMap>();
for (const auto Cont : ContMap) {
if (!SR.isLiveRegion(Cont.first)) {
- State = State->remove<ContainerMap>(Cont.first);
+ // We must keep the container data while it has live iterators to be able
+ // to compare them to the begin and the end of the container.
+ if (!hasLiveIterators(State, Cont.first)) {
+ State = State->remove<ContainerMap>(Cont.first);
+ }
}
}
@@ -1188,6 +1193,22 @@ ProgramStateRef relateIteratorPositions(ProgramStateRef State,
return NewState;
}
+bool hasLiveIterators(ProgramStateRef State, const MemRegion *Cont) {
+ auto RegionMap = State->get<IteratorRegionMap>();
+ for (const auto Reg : RegionMap) {
+ if (Reg.second.getContainer() == Cont)
+ return true;
+ }
+
+ auto SymbolMap = State->get<IteratorSymbolMap>();
+ for (const auto Sym : SymbolMap) {
+ if (Sym.second.getContainer() == Cont)
+ return true;
+ }
+
+ return false;
+}
+
bool isZero(ProgramStateRef State, const NonLoc &Val) {
auto &BVF = State->getBasicVals();
return compare(State, Val,
OpenPOWER on IntegriCloud