From 8557f17d887ab7e70a44f7b674478a16c6eb0119 Mon Sep 17 00:00:00 2001 From: Adam Balogh Date: Mon, 5 Aug 2019 06:45:41 +0000 Subject: [PATCH] [Analyzer] Iterator Checkers - Fix for Crash on Iterator Differences Iterators differences were mistakenly handled as random decrements which causes an assertion. This patch fixes this. llvm-svn: 367802 --- clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp | 12 ++++++++---- clang/test/Analysis/Inputs/system-header-simulator-cxx.h | 3 +++ clang/test/Analysis/diagnostics/explicit-suppression.cpp | 2 +- clang/test/Analysis/iterator-range.cpp | 5 +++++ 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp index 6f1060b..600458a 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp @@ -406,13 +406,15 @@ void IteratorChecker::checkPreCall(const CallEvent &Call, } else if (isRandomIncrOrDecrOperator(Func->getOverloadedOperator())) { if (const auto *InstCall = dyn_cast(&Call)) { // Check for out-of-range incrementions and decrementions - if (Call.getNumArgs() >= 1) { + if (Call.getNumArgs() >= 1 && + Call.getArgExpr(0)->getType()->isIntegralOrEnumerationType()) { verifyRandomIncrOrDecr(C, Func->getOverloadedOperator(), InstCall->getCXXThisVal(), Call.getArgSVal(0)); } } else { - if (Call.getNumArgs() >= 2) { + if (Call.getNumArgs() >= 2 && + Call.getArgExpr(1)->getType()->isIntegralOrEnumerationType()) { verifyRandomIncrOrDecr(C, Func->getOverloadedOperator(), Call.getArgSVal(0), Call.getArgSVal(1)); } @@ -590,14 +592,16 @@ void IteratorChecker::checkPostCall(const CallEvent &Call, return; } else if (isRandomIncrOrDecrOperator(Func->getOverloadedOperator())) { if (const auto *InstCall = dyn_cast(&Call)) { - if (Call.getNumArgs() >= 1) { + if (Call.getNumArgs() >= 1 && + Call.getArgExpr(0)->getType()->isIntegralOrEnumerationType()) { handleRandomIncrOrDecr(C, Func->getOverloadedOperator(), Call.getReturnValue(), InstCall->getCXXThisVal(), Call.getArgSVal(0)); return; } } else { - if (Call.getNumArgs() >= 2) { + if (Call.getNumArgs() >= 2 && + Call.getArgExpr(1)->getType()->isIntegralOrEnumerationType()) { handleRandomIncrOrDecr(C, Func->getOverloadedOperator(), Call.getReturnValue(), Call.getArgSVal(0), Call.getArgSVal(1)); diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h index 5b37e96..30b25b8 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -70,6 +70,9 @@ template struct __vector_iterator { return ptr -= n; } + template + difference_type operator-(const __vector_iterator &rhs); + Ref operator*() const { return *ptr; } Ptr operator->() const { return *ptr; } diff --git a/clang/test/Analysis/diagnostics/explicit-suppression.cpp b/clang/test/Analysis/diagnostics/explicit-suppression.cpp index 2bb9690..6bc0147 100644 --- a/clang/test/Analysis/diagnostics/explicit-suppression.cpp +++ b/clang/test/Analysis/diagnostics/explicit-suppression.cpp @@ -19,6 +19,6 @@ class C { void testCopyNull(C *I, C *E) { std::copy(I, E, (C *)0); #ifndef SUPPRESSED - // expected-warning@../Inputs/system-header-simulator-cxx.h:677 {{Called C++ object pointer is null}} + // expected-warning@../Inputs/system-header-simulator-cxx.h:680 {{Called C++ object pointer is null}} #endif } diff --git a/clang/test/Analysis/iterator-range.cpp b/clang/test/Analysis/iterator-range.cpp index 6fc8939..bc7e082 100644 --- a/clang/test/Analysis/iterator-range.cpp +++ b/clang/test/Analysis/iterator-range.cpp @@ -236,3 +236,8 @@ void good_derived(simple_container c) { *i0; // no-warning } } + +void iter_diff(std::vector &V) { + auto i0 = V.begin(), i1 = V.end(); + ptrdiff_t len = i1 - i0; // no-crash +} -- 2.7.4