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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits