]> granicus.if.org Git - clang/commitdiff
[Analyzer] Iterator Checkers - Fix for Crash on Iterator Differences
authorAdam Balogh <adam.balogh@ericsson.com>
Mon, 5 Aug 2019 06:45:41 +0000 (06:45 +0000)
committerAdam Balogh <adam.balogh@ericsson.com>
Mon, 5 Aug 2019 06:45:41 +0000 (06:45 +0000)
Iterators differences were mistakenly handled as random decrements which
causes an assertion. This patch fixes this.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@367802 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
test/Analysis/Inputs/system-header-simulator-cxx.h
test/Analysis/diagnostics/explicit-suppression.cpp
test/Analysis/iterator-range.cpp

index 6f1060b5f26d982727164c9b54982a8f1d689dde..600458a743ea1f3f13e637850f0c28d3432700ca 100644 (file)
@@ -406,13 +406,15 @@ void IteratorChecker::checkPreCall(const CallEvent &Call,
       } else if (isRandomIncrOrDecrOperator(Func->getOverloadedOperator())) {
         if (const auto *InstCall = dyn_cast<CXXInstanceCall>(&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<CXXInstanceCall>(&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));
index 5b37e96f602774f62ff9b4970e50042c215830af..30b25b85944b6a127f27548713ae76236913292c 100644 (file)
@@ -70,6 +70,9 @@ template <typename T, typename Ptr, typename Ref> struct __vector_iterator {
     return ptr -= n;
   }
 
+  template<typename U, typename Ptr2, typename Ref2>
+  difference_type operator-(const __vector_iterator<U, Ptr2, Ref2> &rhs);
+
   Ref operator*() const { return *ptr; }
   Ptr operator->() const { return *ptr; }
 
index 2bb969059ffbed071438cd6f82a02b0c877862d1..6bc01479b815b5c1bac762061e41adf8d4ce0886 100644 (file)
@@ -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
 }
index 6fc8939c8e846a655f5fa74be8f679ad62949f88..bc7e08263ae216035841667a09777066fda99055 100644 (file)
@@ -236,3 +236,8 @@ void good_derived(simple_container c) {
     *i0; // no-warning
   }
 }
+
+void iter_diff(std::vector<int> &V) {
+  auto i0 = V.begin(), i1 = V.end();
+  ptrdiff_t len = i1 - i0; // no-crash
+}