baloghadamsoftware created this revision.
baloghadamsoftware added reviewers: NoQ, gamesh411, martong, balazske.
baloghadamsoftware added a project: clang.
Herald added subscribers: ASDenysPetrov, steakhal, Charusso, dkrupp,
donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, rnkovacs, szepet, xazax.hun,
whisperity.
Herald added a reviewer: Szelethus.
The patch that introduces handling pointers implemented as iterators may cause
crash in some projects because pointer difference is mistakenly handled as
pointer decrement. (Similair case for iterators implemented as class instances
are already handled correctly.) This patch fixes this issue.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D83295
Files:
clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp
clang/test/Analysis/iterator-modeling.cpp
clang/test/Analysis/iterator-range.cpp
Index: clang/test/Analysis/iterator-range.cpp
===================================================================
--- clang/test/Analysis/iterator-range.cpp
+++ clang/test/Analysis/iterator-range.cpp
@@ -935,3 +935,7 @@
// expected-note@-1{{Iterator decremented ahead of its valid range}}
}
+void ptr_iter_diff(cont_with_ptr_iterator<S> &c) {
+ auto i0 = c.begin(), i1 = c.end();
+ ptrdiff_t len = i1 - i0; // no-crash
+}
Index: clang/test/Analysis/iterator-modeling.cpp
===================================================================
--- clang/test/Analysis/iterator-modeling.cpp
+++ clang/test/Analysis/iterator-modeling.cpp
@@ -1972,6 +1972,11 @@
clang_analyzer_express(clang_analyzer_iterator_position(i2)); //
expected-warning{{$c.end() - 2}}
}
+void ptr_iter_diff(cont_with_ptr_iterator<int> &c) {
+ auto i0 = c.begin(), i1 = c.end();
+ ptrdiff_t len = i1 - i0; // no-crash
+}
+
void clang_analyzer_printState();
void print_state(std::vector<int> &V) {
Index: clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp
@@ -169,6 +169,8 @@
verifyDereference(C, LVal);
} else if (isRandomIncrOrDecrOperator(OK)) {
SVal RVal = State->getSVal(BO->getRHS(), C.getLocationContext());
+ if (!BO->getRHS()->getType()->isIntegralOrEnumerationType())
+ return;
verifyRandomIncrOrDecr(C, BinaryOperator::getOverloadedOperator(OK), LVal,
RVal);
}
Index: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
@@ -272,6 +272,8 @@
handleComparison(C, BO, Result, LVal, RVal,
BinaryOperator::getOverloadedOperator(OK));
} else if (isRandomIncrOrDecrOperator(OK)) {
+ if (!BO->getRHS()->getType()->isIntegralOrEnumerationType())
+ return;
handlePtrIncrOrDecr(C, BO->getLHS(),
BinaryOperator::getOverloadedOperator(OK), RVal);
}
@@ -461,6 +463,9 @@
RPos = getIteratorPosition(State, RVal);
}
+ if (!LPos || !RPos)
+ return;
+
// We cannot make assumptions on `UnknownVal`. Let us conjure a symbol
// instead.
if (RetVal.isUnknown()) {
Index: clang/test/Analysis/iterator-range.cpp
===================================================================
--- clang/test/Analysis/iterator-range.cpp
+++ clang/test/Analysis/iterator-range.cpp
@@ -935,3 +935,7 @@
// expected-note@-1{{Iterator decremented ahead of its valid range}}
}
+void ptr_iter_diff(cont_with_ptr_iterator<S> &c) {
+ auto i0 = c.begin(), i1 = c.end();
+ ptrdiff_t len = i1 - i0; // no-crash
+}
Index: clang/test/Analysis/iterator-modeling.cpp
===================================================================
--- clang/test/Analysis/iterator-modeling.cpp
+++ clang/test/Analysis/iterator-modeling.cpp
@@ -1972,6 +1972,11 @@
clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$c.end() - 2}}
}
+void ptr_iter_diff(cont_with_ptr_iterator<int> &c) {
+ auto i0 = c.begin(), i1 = c.end();
+ ptrdiff_t len = i1 - i0; // no-crash
+}
+
void clang_analyzer_printState();
void print_state(std::vector<int> &V) {
Index: clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/IteratorRangeChecker.cpp
@@ -169,6 +169,8 @@
verifyDereference(C, LVal);
} else if (isRandomIncrOrDecrOperator(OK)) {
SVal RVal = State->getSVal(BO->getRHS(), C.getLocationContext());
+ if (!BO->getRHS()->getType()->isIntegralOrEnumerationType())
+ return;
verifyRandomIncrOrDecr(C, BinaryOperator::getOverloadedOperator(OK), LVal,
RVal);
}
Index: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
@@ -272,6 +272,8 @@
handleComparison(C, BO, Result, LVal, RVal,
BinaryOperator::getOverloadedOperator(OK));
} else if (isRandomIncrOrDecrOperator(OK)) {
+ if (!BO->getRHS()->getType()->isIntegralOrEnumerationType())
+ return;
handlePtrIncrOrDecr(C, BO->getLHS(),
BinaryOperator::getOverloadedOperator(OK), RVal);
}
@@ -461,6 +463,9 @@
RPos = getIteratorPosition(State, RVal);
}
+ if (!LPos || !RPos)
+ return;
+
// We cannot make assumptions on `UnknownVal`. Let us conjure a symbol
// instead.
if (RetVal.isUnknown()) {
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits