[clang] 23022b9 - [Analyzer][NFC] Separate white-box tests for iterator modelling from iterator checker tests

Adam Balogh via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 14 07:31:25 PST 2019


Author: Adam Balogh
Date: 2019-11-14T16:32:19+01:00
New Revision: 23022b93293676890b2c707616aaa8327f0e3708

URL: https://github.com/llvm/llvm-project/commit/23022b93293676890b2c707616aaa8327f0e3708
DIFF: https://github.com/llvm/llvm-project/commit/23022b93293676890b2c707616aaa8327f0e3708.diff

LOG: [Analyzer][NFC] Separate white-box tests for iterator modelling from iterator checker tests

The recently committed debug.IteratorDebugging checker enables
standalone white-box testing of the modelling of containers and
iterators. For the three checkers based on iterator modelling only
simple tests are needed.

Differential Revision: https://reviews.llvm.org/D70123

Added: 
    clang/test/Analysis/iterator-modelling.cpp

Modified: 
    clang/test/Analysis/Inputs/system-header-simulator-cxx.h
    clang/test/Analysis/diagnostics/explicit-suppression.cpp
    clang/test/Analysis/invalidated-iterator.cpp
    clang/test/Analysis/iterator-range.cpp
    clang/test/Analysis/mismatched-iterator.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h
index 26248a4d1f51..77b87627f6e3 100644
--- a/clang/test/Analysis/Inputs/system-header-simulator-cxx.h
+++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx.h
@@ -74,8 +74,12 @@ template <typename T, typename Ptr, typename Ref> struct __vector_iterator {
   
diff erence_type operator-(const __vector_iterator<U, Ptr2, Ref2> &rhs);
 
   Ref operator*() const { return *ptr; }
-  Ptr operator->() const { return *ptr; }
+  Ptr operator->() const { return ptr; }
 
+  Ref operator[](
diff erence_type n) {
+    return *(ptr+n);
+  }
+  
   bool operator==(const iterator &rhs) const { return ptr == rhs.ptr; }
   bool operator==(const const_iterator &rhs) const { return ptr == rhs.ptr; }
 
@@ -125,8 +129,12 @@ template <typename T, typename Ptr, typename Ref> struct __deque_iterator {
   }
 
   Ref operator*() const { return *ptr; }
-  Ptr operator->() const { return *ptr; }
+  Ptr operator->() const { return ptr; }
 
+  Ref operator[](
diff erence_type n) {
+    return *(ptr+n);
+  }
+  
   bool operator==(const iterator &rhs) const { return ptr == rhs.ptr; }
   bool operator==(const const_iterator &rhs) const { return ptr == rhs.ptr; }
 
@@ -165,7 +173,7 @@ template <typename T, typename Ptr, typename Ref> struct __list_iterator {
   }
 
   Ref operator*() const { return item->data; }
-  Ptr operator->() const { return item->data; }
+  Ptr operator->() const { return &item->data; }
 
   bool operator==(const iterator &rhs) const { return item == rhs->item; }
   bool operator==(const const_iterator &rhs) const { return item == rhs->item; }
@@ -201,7 +209,7 @@ template <typename T, typename Ptr, typename Ref> struct __fwdl_iterator {
     return tmp;
   }
   Ref operator*() const { return item->data; }
-  Ptr operator->() const { return item->data; }
+  Ptr operator->() const { return &item->data; }
 
   bool operator==(const iterator &rhs) const { return item == rhs->item; }
   bool operator==(const const_iterator &rhs) const { return item == rhs->item; }
@@ -255,15 +263,16 @@ namespace std {
 
   template<typename T>
   class vector {
+    T *_start;
+    T *_finish;
+    T *_end_of_storage;
+
+  public:
     typedef T value_type;
     typedef size_t size_type;
     typedef __vector_iterator<T, T *, T &> iterator;
     typedef __vector_iterator<T, const T *, const T &> const_iterator;
 
-    T *_start;
-    T *_finish;
-    T *_end_of_storage;
-  public:
     vector() : _start(0), _finish(0), _end_of_storage(0) {}
     template <typename InputIterator>
     vector(InputIterator first, InputIterator last);
@@ -333,6 +342,7 @@ namespace std {
       T data;
       __item *prev, *next;
     } *_start, *_finish;
+
   public:
     typedef T value_type;
     typedef size_t size_type;
@@ -399,15 +409,16 @@ namespace std {
 
   template<typename T>
   class deque {
+    T *_start;
+    T *_finish;
+    T *_end_of_storage;
+
+  public:
     typedef T value_type;
     typedef size_t size_type;
     typedef __deque_iterator<T, T *, T &> iterator;
     typedef __deque_iterator<T, const T *, const T &> const_iterator;
 
-    T *_start;
-    T *_finish;
-    T *_end_of_storage;
-  public:
     deque() : _start(0), _finish(0), _end_of_storage(0) {}
     template <typename InputIterator>
     deque(InputIterator first, InputIterator last);
@@ -483,6 +494,7 @@ namespace std {
       T data;
       __item *next;
     } *_start;
+
   public:
     typedef T value_type;
     typedef size_t size_type;

diff  --git a/clang/test/Analysis/diagnostics/explicit-suppression.cpp b/clang/test/Analysis/diagnostics/explicit-suppression.cpp
index c10aaa528e0d..f7db7a280545 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 at ../Inputs/system-header-simulator-cxx.h:686 {{Called C++ object pointer is null}}
+  // expected-warning at ../Inputs/system-header-simulator-cxx.h:698 {{Called C++ object pointer is null}}
 #endif
 }

diff  --git a/clang/test/Analysis/invalidated-iterator.cpp b/clang/test/Analysis/invalidated-iterator.cpp
index de37c9c055b9..4505aedd4e36 100644
--- a/clang/test/Analysis/invalidated-iterator.cpp
+++ b/clang/test/Analysis/invalidated-iterator.cpp
@@ -5,760 +5,119 @@
 
 void clang_analyzer_warnIfReached();
 
-void bad_copy_assign_operator1_list(std::list<int> &L1,
-                                    const std::list<int> &L2) {
-  auto i0 = L1.cbegin();
-  L1 = L2;
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-  clang_analyzer_warnIfReached();
+void normal_dereference(std::vector<int> &V) {
+  auto i = V.cbegin();
+  *i; // no-warning
 }
 
-void bad_copy_assign_operator1_vector(std::vector<int> &V1,
-                                      const std::vector<int> &V2) {
-  auto i0 = V1.cbegin();
-  V1 = V2;
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void invalidated_dereference(std::vector<int> &V) {
+  auto i = V.cbegin();
+  V.erase(i);
+  *i; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void bad_copy_assign_operator1_deque(std::deque<int> &D1,
-                                     const std::deque<int> &D2) {
-  auto i0 = D1.cbegin();
-  D1 = D2;
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void normal_prefix_increment(std::vector<int> &V) {
+  auto i = V.cbegin();
+  ++i; // no-warning
 }
 
-void bad_copy_assign_operator1_forward_list(std::forward_list<int> &FL1,
-                                            const std::forward_list<int> &FL2) {
-  auto i0 = FL1.cbegin();
-  FL1 = FL2;
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void invalidated_prefix_increment(std::vector<int> &V) {
+  auto i = V.cbegin();
+  V.erase(i);
+  ++i; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void bad_assign1_list(std::list<int> &L, int n) {
-  auto i0 = L.cbegin();
-  L.assign(10, n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void normal_prefix_decrement(std::vector<int> &V) {
+  auto i = ++V.cbegin();
+  --i; // no-warning
 }
 
-void bad_assign1_vector(std::vector<int> &V, int n) {
-  auto i0 = V.cbegin();
-  V.assign(10, n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void invalidated_prefix_decrement(std::vector<int> &V) {
+  auto i = ++V.cbegin();
+  V.erase(i);
+  --i; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void bad_assign1_deque(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin();
-  D.assign(10, n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void normal_postfix_increment(std::vector<int> &V) {
+  auto i = V.cbegin();
+  i++; // no-warning
 }
 
-void bad_assign1_forward_list(std::forward_list<int> &FL, int n) {
-  auto i0 = FL.cbegin();
-  FL.assign(10, n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void invalidated_postfix_increment(std::vector<int> &V) {
+  auto i = V.cbegin();
+  V.erase(i);
+  i++; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void good_clear1_list(std::list<int> &L) {
-  auto i0 = L.cend();
-  L.clear();
-  --i0; // no-warning
+void normal_postfix_decrement(std::vector<int> &V) {
+  auto i = ++V.cbegin();
+  i--; // no-warning
 }
 
-void bad_clear1_list(std::list<int> &L) {
-  auto i0 = L.cbegin(), i1 = L.cend();
-  L.clear();
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void invalidated_postfix_decrement(std::vector<int> &V) {
+  auto i = ++V.cbegin();
+  V.erase(i);
+  i--; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void bad_clear1_vector(std::vector<int> &V) {
-  auto i0 = V.cbegin(), i1 = V.cend();
-  V.clear();
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void normal_increment_by_2(std::vector<int> &V) {
+  auto i = V.cbegin();
+  i += 2; // no-warning
 }
 
-void bad_clear1_vector_decr(std::vector<int> &V) {
-  auto i0 = V.cbegin(), i1 = V.cend();
-  V.clear();
-  --i1; // expected-warning{{Invalidated iterator accessed}}
+void invalidated_increment_by_2(std::vector<int> &V) {
+  auto i = V.cbegin();
+  V.erase(i);
+  i += 2; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void bad_clear1_deque(std::deque<int> &D) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.clear();
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void normal_increment_by_2_copy(std::vector<int> &V) {
+  auto i = V.cbegin();
+  auto j = i + 2; // no-warning
 }
 
-void bad_clear1_deque_decr(std::deque<int> &D) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.clear();
-  --i1; // expected-warning{{Invalidated iterator accessed}}
+void invalidated_increment_by_2_copy(std::vector<int> &V) {
+  auto i = V.cbegin();
+  V.erase(i);
+  auto j = i + 2; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void good_push_back1_list(std::list<int> &L, int n) {
-  auto i0 = L.cbegin(), i1 = L.cend();
-  L.push_back(n);
-  *i0; // no-warning
-  --i1; // no-warning
+void normal_decrement_by_2(std::vector<int> &V) {
+  auto i = V.cbegin();
+  i -= 2; // no-warning
 }
 
-void good_push_back1_vector(std::vector<int> &V, int n) {
-  auto i0 = V.cbegin(), i1 = V.cend();
-  V.push_back(n);
-  *i0; // no-warning
+void invalidated_decrement_by_2(std::vector<int> &V) {
+  auto i = V.cbegin();
+  V.erase(i);
+  i -= 2; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void bad_push_back1_vector(std::vector<int> &V, int n) {
-  auto i0 = V.cbegin(), i1 = V.cend();
-  V.push_back(n);
-  --i1; // expected-warning{{Invalidated iterator accessed}}
+void normal_decrement_by_2_copy(std::vector<int> &V) {
+  auto i = V.cbegin();
+  auto j = i - 2; // no-warning
 }
 
-void bad_push_back1_deque(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.push_back(n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
+void invalidated_decrement_by_2_copy(std::vector<int> &V) {
+  auto i = V.cbegin();
+  V.erase(i);
+  auto j = i - 2; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void bad_push_back1_deque_decr(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.push_back(n);
-  --i1; // expected-warning{{Invalidated iterator accessed}}
+void normal_subscript(std::vector<int> &V) {
+  auto i = V.cbegin();
+  i[1]; // no-warning
 }
 
-void good_emplace_back1_list(std::list<int> &L, int n) {
-  auto i0 = L.cbegin(), i1 = L.cend();
-  L.emplace_back(n);
-  *i0; // no-warning
-  --i1; // no-warning
+void invalidated_subscript(std::vector<int> &V) {
+  auto i = V.cbegin();
+  V.erase(i);
+  i[1]; // expected-warning{{Invalidated iterator accessed}}
 }
 
-void good_emplace_back1_vector(std::vector<int> &V, int n) {
-  auto i0 = V.cbegin(), i1 = V.cend();
-  V.emplace_back(n);
-  *i0; // no-warning
+void assignment(std::vector<int> &V) {
+  auto i = V.cbegin();
+  V.erase(i);
+  auto j = V.cbegin(); // no-warning
 }
 
-void bad_emplace_back1_vector(std::vector<int> &V, int n) {
-  auto i0 = V.cbegin(), i1 = V.cend();
-  V.emplace_back(n);
-  --i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_emplace_back1_deque(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.emplace_back(n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_emplace_back1_deque_decr(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.emplace_back(n);
-  --i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_pop_back1_list(std::list<int> &L, int n) {
-  auto i0 = L.cbegin(), i1 = L.cend(), i2 = i1--;
-  L.pop_back();
-  *i0; // no-warning
-  *i2; // no-warning
-}
-
-void bad_pop_back1_list(std::list<int> &L, int n) {
-  auto i0 = L.cbegin(), i1 = L.cend(), i2 = i1--;
-  L.pop_back();
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_pop_back1_vector(std::vector<int> &V, int n) {
-  auto i0 = V.cbegin(), i1 = V.cend(), i2 = i1--;
-  V.pop_back();
-  *i0; // no-warning
-}
-
-void bad_pop_back1_vector(std::vector<int> &V, int n) {
-  auto i0 = V.cbegin(), i1 = V.cend(), i2 = i1--;
-  V.pop_back();
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_pop_back1_vector_decr(std::vector<int> &V, int n) {
-  auto i0 = V.cbegin(), i1 = V.cend(), i2 = i1--;
-  V.pop_back();
-  --i2; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_pop_back1_deque(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend(), i2 = i1--;
-  D.pop_back();
-  *i0; // no-warning
-}
-
-void bad_pop_back1_deque(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend(), i2 = i1--;
-  D.pop_back();
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_pop_back1_deque_decr(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend(), i2 = i1--;
-  D.pop_back();
-  --i2; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_push_front1_list(std::list<int> &L, int n) {
-  auto i0 = L.cbegin(), i1 = L.cend();
-  L.push_front(n);
-  *i0; // no-warning
-  --i1; // no-warning
-}
-
-void bad_push_front1_deque(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.push_front(n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_push_front1_deque_decr(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.push_front(n);
-  --i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_push_front1_forward_list(std::forward_list<int> &FL, int n) {
-  auto i0 = FL.cbegin(), i1 = FL.cend();
-  FL.push_front(n);
-  *i0; // no-warning
-}
-
-void good_emplace_front1_list(std::list<int> &L, int n) {
-  auto i0 = L.cbegin(), i1 = L.cend();
-  L.emplace_front(n);
-  *i0; // no-warning
-  --i1; // no-warning
-}
-
-void bad_emplace_front1_deque(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.emplace_front(n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_emplace_front1_deque_decr(std::deque<int> &D, int n) {
-  auto i0 = D.cbegin(), i1 = D.cend();
-  D.emplace_front(n);
-  --i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_emplace_front1_forward_list(std::forward_list<int> &FL, int n) {
-  auto i0 = FL.cbegin(), i1 = FL.cend();
-  FL.emplace_front(n);
-  *i0; // no-warning
-}
-
-void good_pop_front1_list(std::list<int> &L, int n) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  L.pop_front();
-  *i1; // no-warning
-}
-
-void bad_pop_front1_list(std::list<int> &L, int n) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  L.pop_front();
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_pop_front1_deque(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.pop_front();
-  *i1; // no-warning
-}
-
-void bad_pop_front1_deque(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.pop_front();
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_pop_front1_forward_list(std::forward_list<int> &FL, int n) {
-  auto i1 = FL.cbegin(), i0 = i1++;
-  FL.pop_front();
-  *i1; // no-warning
-}
-
-void bad_pop_front1_forward_list(std::forward_list<int> &FL, int n) {
-  auto i1 = FL.cbegin(), i0 = i1++;
-  FL.pop_front();
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert1_list1(std::list<int> &L, int n) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  L.insert(i1, n);
-  *i0; // no-warning
-  *i1; // no-warning
-}
-
-void good_insert1_list2(std::list<int> &L, int n) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  i1 = L.insert(i1, n);
-  *i1; // no-warning
-}
-
-void good_insert1_vector1(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.insert(i1, n);
-  *i0; // no-warning
-}
-
-void good_insert1_vector2(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  i1 = V.insert(i1, n);
-  *i1; // no-warning
-}
-
-void bad_insert1_vector(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.insert(i1, n);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert1_deque(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  i0 = D.insert(i1, n);
-  *i0; // no-warning
-}
-
-void bad_insert1_deque1(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.insert(i1, n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_insert1_deque2(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.insert(i1, n);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert2_list1(std::list<int> &L, int n) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  L.insert(i1, std::move(n));
-  *i0; // no-warning
-  *i1; // no-warning
-}
-
-void good_insert2_list2(std::list<int> &L, int n) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  i1 = L.insert(i1, std::move(n));
-  *i1; // no-warning
-}
-
-void good_insert2_vector1(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.insert(i1, std::move(n));
-  *i0; // no-warning
-}
-
-void good_insert2_vector2(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  i1 = V.insert(i1, std::move(n));
-  *i1; // no-warning
-}
-
-void bad_insert2_vector(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.insert(i1, std::move(n));
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert2_deque(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  i1 = D.insert(i1, std::move(n));
-  *i1; // no-warning
-}
-
-void bad_insert2_deque1(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.insert(i1, std::move(n));
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_insert2_deque2(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.insert(i1, std::move(n));
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert3_list1(std::list<int> &L, int n) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  L.insert(i1, 10, n);
-  *i0; // no-warning
-  *i1; // no-warning
-}
-
-void good_insert3_list2(std::list<int> &L, int n) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  i1 = L.insert(i1, 10, n);
-  *i1; // no-warning
-}
-
-void good_insert3_vector1(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.insert(i1, 10, n);
-  *i0; // no-warning
-}
-
-void good_insert3_vector2(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  i1 = V.insert(i1, 10, n);
-  *i1; // no-warning
-}
-
-void bad_insert3_vector(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.insert(i1, 10, n);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert3_deque(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  i1 = D.insert(i1, 10, std::move(n));
-  *i1; // no-warning
-}
-
-void bad_insert3_deque1(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.insert(i1, 10, std::move(n));
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_insert3_deque2(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.insert(i1, 10, std::move(n));
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert4_list1(std::list<int> &L1, std::list<int> &L2, int n) {
-  auto i1 = L1.cbegin(), i0 = i1++;
-  L1.insert(i1, L2.cbegin(), L2.cend());
-  *i0; // no-warning
-  *i1; // no-warning
-}
-
-void good_insert4_list2(std::list<int> &L1, std::list<int> &L2, int n) {
-  auto i1 = L1.cbegin(), i0 = i1++;
-  i1 = L1.insert(i1, L2.cbegin(), L2.cend());
-  *i1; // no-warning
-}
-
-void good_insert4_vector1(std::vector<int> &V1, std::vector<int> &V2, int n) {
-  auto i1 = V1.cbegin(), i0 = i1++;
-  V1.insert(i1, V2.cbegin(), V2.cend());
-  *i0; // no-warning
-}
-
-void good_insert4_vector2(std::vector<int> &V1, std::vector<int> &V2, int n) {
-  auto i1 = V1.cbegin(), i0 = i1++;
-  i1 = V1.insert(i1, V2.cbegin(), V2.cend());
-  *i1; // no-warning
-}
-
-void bad_insert4_vector(std::vector<int> &V1, std::vector<int> &V2, int n) {
-  auto i1 = V1.cbegin(), i0 = i1++;
-  V1.insert(i1, V2.cbegin(), V2.cend());
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert4_deque(std::deque<int> &D1, std::deque<int> &D2, int n) {
-  auto i1 = D1.cbegin(), i0 = i1++;
-  i1 = D1.insert(i1, D2.cbegin(), D2.cend());
-  *i1; // no-warning
-}
-
-void bad_insert4_deque1(std::deque<int> &D1, std::deque<int> &D2, int n) {
-  auto i1 = D1.cbegin(), i0 = i1++;
-  D1.insert(i1, D2.cbegin(), D2.cend());
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_insert4_deque2(std::deque<int> &D1, std::deque<int> &D2, int n) {
-  auto i1 = D1.cbegin(), i0 = i1++;
-  D1.insert(i1, D2.cbegin(), D2.cend());
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert5_list1(std::list<int> &L) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  L.insert(i1, {1, 2, 3, 4});
-  *i0; // no-warning
-  *i1; // no-warning
-}
-
-void good_insert5_list2(std::list<int> &L) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  i1 = L.insert(i1, {1, 2, 3, 4});
-  *i1; // no-warning
-}
-
-void good_insert5_vector1(std::vector<int> &V) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.insert(i1, {1, 2, 3, 4});
-  *i0; // no-warning
-}
-
-void good_insert5_vector2(std::vector<int> &V) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  i1 = V.insert(i1, {1, 2, 3, 4});
-  *i1; // no-warning
-}
-
-void bad_insert5_vector(std::vector<int> &V) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.insert(i1, {1, 2, 3, 4});
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_insert5_deque(std::deque<int> &D) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  i1 = D.insert(i1, {1, 2, 3, 4});
-  *i1; // no-warning
-}
-
-void bad_insert5_deque1(std::deque<int> &D) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.insert(i1, {1, 2, 3, 4});
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_insert5_deque2(std::deque<int> &D) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.insert(i1, {1, 2, 3, 4});
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_emplace1_list(std::list<int> &L, int n) {
-  auto i1 = L.cbegin(), i0 = i1++;
-  L.emplace(i1, n);
-  *i0; // no-warning
-  *i1; // no-warning
-}
-
-void good_emplace1_vector(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.emplace(i1, n);
-  *i0; // no-warning
-}
-
-void bad_emplace1_vector(std::vector<int> &V, int n) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.emplace(i1, n);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_emplace1_deque1(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.emplace(i1, n);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_emplace1_deque2(std::deque<int> &D, int n) {
-  auto i1 = D.cbegin(), i0 = i1++;
-  D.emplace(i1, n);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_erase1_list1(std::list<int> &L) {
-  auto i2 = L.cbegin(), i0 = i2++, i1 = i2++;
-  L.erase(i1);
-  *i0; // no-warning
-  *i2; // no-warning
-}
-
-void good_erase1_list2(std::list<int> &L) {
-  auto i0 = L.cbegin();
-  i0 = L.erase(i0);
-  *i0; // no-warning
-}
-
-void bad_erase1_list(std::list<int> &L) {
-  auto i0 = L.cbegin();
-  L.erase(i0);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_erase1_vector1(std::vector<int> &V) {
-  auto i2 = V.cbegin(), i0 = i2++, i1 = i2++;
-  V.erase(i1);
-  *i0; // no-warning
-}
-
-void good_erase1_vector2(std::vector<int> &V) {
-  auto i0 = V.cbegin();
-  i0 = V.erase(i0);
-  *i0; // no-warning
-}
-
-void bad_erase1_vector1(std::vector<int> &V) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.erase(i0);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase1_vector2(std::vector<int> &V) {
-  auto i1 = V.cbegin(), i0 = i1++;
-  V.erase(i0);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_erase1_deque(std::deque<int> &D) {
-  auto i0 = D.cbegin();
-  i0 = D.erase(i0);
-  *i0; // no-warning
-}
-
-void bad_erase1_deque1(std::deque<int> &D) {
-  auto i2 = D.cbegin(), i0 = i2++, i1 = i2++;
-  D.erase(i1);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase1_deque2(std::deque<int> &D) {
-  auto i2 = D.cbegin(), i0 = i2++, i1 = i2++;
-  D.erase(i1);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase1_deque3(std::deque<int> &D) {
-  auto i2 = D.cbegin(), i0 = i2++, i1 = i2++;
-  D.erase(i1);
-  *i2; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_erase2_list1(std::list<int> &L) {
-  auto i3 = L.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;
-  L.erase(i1, i3);
-  *i0; // no-warning
-  *i3; // no-warning
-}
-
-void good_erase2_list2(std::list<int> &L) {
-  auto i2 = L.cbegin(), i0 = i2++, i1 = i2++;
-  i0 = L.erase(i0, i2);
-  *i0; // no-warning
-}
-
-void bad_erase2_list1(std::list<int> &L) {
-  auto i2 = L.cbegin(), i0 = i2++, i1 = i2++;
-  L.erase(i0, i2);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase2_list2(std::list<int> &L) {
-  auto i2 = L.cbegin(), i0 = i2++, i1 = i2++;
-  L.erase(i0, i2);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_erase2_vector1(std::vector<int> &V) {
-  auto i3 = V.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;;
-  V.erase(i1, i3);
-  *i0; // no-warning
-}
-
-void good_erase2_vector2(std::vector<int> &V) {
-  auto i2 = V.cbegin(), i0 = i2++, i1 = i2++;
-  i0 = V.erase(i0, i2);
-  *i0; // no-warning
-}
-
-void bad_erase2_vector1(std::vector<int> &V) {
-  auto i2 = V.cbegin(), i0 = i2++, i1 = i2++;
-  V.erase(i0, i2);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase2_vector2(std::vector<int> &V) {
-  auto i2 = V.cbegin(), i0 = i2++, i1 = i2++;
-  V.erase(i0, i2);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase2_vector3(std::vector<int> &V) {
-  auto i2 = V.cbegin(), i0 = i2++, i1 = i2++;
-  V.erase(i0, i2);
-  *i2; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_erase2_deque(std::deque<int> &D) {
-  auto i2 = D.cbegin(), i0 = i2++, i1 = i2++;
-  i0 = D.erase(i0, i2);
-  *i0; // no-warning
-}
-
-void bad_erase2_deque1(std::deque<int> &D) {
-  auto i3 = D.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;
-  D.erase(i1, i3);
-  *i0; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase2_deque2(std::deque<int> &D) {
-  auto i3 = D.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;
-  D.erase(i1, i3);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase2_deque3(std::deque<int> &D) {
-  auto i3 = D.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;
-  D.erase(i1, i3);
-  *i2; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase2_deque4(std::deque<int> &D) {
-  auto i3 = D.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;
-  D.erase(i1, i3);
-  *i3; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_erase_after1_forward_list1(std::forward_list<int> &FL) {
-  auto i2 = FL.cbegin(), i0 = i2++, i1 = i2++;
-  FL.erase_after(i0);
-  *i0; // no-warning
-  *i2; // no-warning
-}
-
-void good_erase_after1_forward_lis2(std::forward_list<int> &FL) {
-  auto i1 = FL.cbegin(), i0 = i1++;
-  i1 = FL.erase_after(i0);
-  *i1; // no-warning
-}
-
-void bad_erase_after1_forward_list(std::forward_list<int> &FL) {
-  auto i1 = FL.cbegin(), i0 = i1++;
-  FL.erase_after(i0);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void good_erase_after2_forward_list1(std::forward_list<int> &FL) {
-  auto i3 = FL.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;
-  FL.erase_after(i0, i3);
-  *i0; // no-warning
-  *i3; // no-warning
-}
-
-void good_erase_after2_forward_list2(std::forward_list<int> &FL) {
-  auto i3 = FL.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;
-  i2 = FL.erase_after(i0, i3);
-  *i2; // no-warning
-}
-
-void bad_erase_after2_forward_list1(std::forward_list<int> &FL) {
-  auto i3 = FL.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;
-  FL.erase_after(i0, i3);
-  *i1; // expected-warning{{Invalidated iterator accessed}}
-}
-
-void bad_erase_after2_forward_list2(std::forward_list<int> &FL) {
-  auto i3 = FL.cbegin(), i0 = i3++, i1 = i3++, i2 = i3++;
-  FL.erase_after(i0, i3);
-  *i2; // expected-warning{{Invalidated iterator accessed}}
-}

diff  --git a/clang/test/Analysis/iterator-modelling.cpp b/clang/test/Analysis/iterator-modelling.cpp
new file mode 100644
index 000000000000..92427528e7c0
--- /dev/null
+++ b/clang/test/Analysis/iterator-modelling.cpp
@@ -0,0 +1,1972 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=false %s -verify
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+template <typename Container>
+long clang_analyzer_container_begin(const Container&);
+template <typename Container>
+long clang_analyzer_container_end(const Container&);
+template <typename Iterator>
+long clang_analyzer_iterator_position(const Iterator&);
+template <typename Iterator>
+void* clang_analyzer_iterator_container(const Iterator&);
+template <typename Iterator>
+bool clang_analyzer_iterator_validity(const Iterator&);
+
+void clang_analyzer_denote(long, const char*);
+void clang_analyzer_express(long);
+void clang_analyzer_eval(bool);
+void clang_analyzer_warnIfReached();
+
+void begin(const std::vector<int> &v) {
+  auto i = v.begin();
+
+  clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}}
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin()}}
+
+  if (i != v.begin()) {
+    clang_analyzer_warnIfReached();
+  }
+}
+
+void end(const std::vector<int> &v) {
+  auto i = v.end();
+
+  clang_analyzer_eval(clang_analyzer_iterator_container(i) == &v); // expected-warning{{TRUE}}
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end()}}
+
+  if (i != v.end()) {
+    clang_analyzer_warnIfReached();
+  }
+}
+
+void prefix_increment(const std::vector<int> &v) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto j = ++i;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 1}}
+}
+
+void prefix_decrement(const std::vector<int> &v) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto j = --i;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 1}}
+}
+
+void postfix_increment(const std::vector<int> &v) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto j = i++;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin()}}
+}
+
+void postfix_decrement(const std::vector<int> &v) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto j = i--;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end()}}
+}
+
+void plus_equal(const std::vector<int> &v) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  i += 2;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 2}}
+}
+
+void minus_equal(const std::vector<int> &v) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  i -= 2;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 2}}
+}
+
+void copy(const std::vector<int> &v) {
+  auto i1 = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto i2 = i1;
+
+  clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end()}}
+}
+
+void plus(const std::vector<int> &v) {
+  auto i1 = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto i2 = i1 + 2;
+
+  clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin() + 2}}
+}
+
+void minus(const std::vector<int> &v) {
+  auto i1 = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto i2 = i1 - 2;
+
+  clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 2}}
+}
+
+void copy_and_increment1(const std::vector<int> &v) {
+  auto i1 = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto i2 = i1;
+  ++i1;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.begin() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin()}}
+}
+
+void copy_and_increment2(const std::vector<int> &v) {
+  auto i1 = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto i2 = i1;
+  ++i2;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.begin() + 1}}
+}
+
+void copy_and_decrement1(const std::vector<int> &v) {
+  auto i1 = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto i2 = i1;
+  --i1;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.end() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end()}}
+}
+
+void copy_and_decrement2(const std::vector<int> &v) {
+  auto i1 = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto i2 = i1;
+  --i2;
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); //expected-warning{{$v.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 1}}
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// C O N T A I N E R   A S S I G N M E N T S
+///
+////////////////////////////////////////////////////////////////////////////////
+
+// Copy
+
+void list_copy_assignment(std::list<int> &L1, const std::list<int> &L2) {
+  auto i0 = L1.cbegin();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  L1 = L2;
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+}
+
+void vector_copy_assignment(std::vector<int> &V1, const std::vector<int> &V2) {
+  auto i0 = V1.cbegin();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  V1 = V2;
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+}
+
+void deque_copy_assignment(std::deque<int> &D1, const std::deque<int> &D2) {
+  auto i0 = D1.cbegin();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  D1 = D2;
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+}
+
+void forward_list_copy_assignment(std::forward_list<int> &FL1,
+                                  const std::forward_list<int> &FL2) {
+  auto i0 = FL1.cbegin();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  FL1 = FL2;
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+}
+
+// Move
+
+void list_move_assignment(std::list<int> &L1, std::list<int> &L2) {
+  auto i0 = L1.cbegin(), i1 = L2.cbegin(), i2 = --L2.cend(), i3 = L2.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L2), "$L2.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L2), "$L2.end()");
+
+  L1 = std::move(L2);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE.
+
+  clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &L1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &L1); // expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L1)); // expected-warning{{$L2.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L2.begin()}}
+}
+
+void vector_move_assignment(std::vector<int> &V1, std::vector<int> &V2) {
+  auto i0 = V1.cbegin(), i1 = V2.cbegin(), i2 = --V2.cend(), i3 = V2.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V2), "$V2.begin()");
+
+  V1 = std::move(V2);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE.
+
+  clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &V1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &V1); // expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V1)); // expected-warning{{$V2.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V2.begin()}}
+}
+
+void deque_move_assignment(std::deque<int> &D1, std::deque<int> &D2) {
+  auto i0 = D1.cbegin(), i1 = D2.cbegin(), i2 = --D2.cend(), i3 = D2.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D2), "$D2.begin()");
+
+  D1 = std::move(D2);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}} FIXME: Should be FALSE.
+
+  clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &D1); // expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &D1); // expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D1)); // expected-warning{{$D2.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$D2.begin()}}
+}
+
+void forward_list_move_assignment(std::forward_list<int> &FL1,
+                                  std::forward_list<int> &FL2) {
+  auto i0 = FL1.cbegin(), i1 = FL2.cbegin(), i2 = FL2.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL2), "$FL2.begin()");
+
+  FL1 = std::move(FL2);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}} FIXME: Should be FALSE.
+
+  clang_analyzer_eval(clang_analyzer_iterator_container(i1) == &FL1); // expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL1)); // expected-warning{{$FL2.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL2.begin()}}
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+///
+/// C O N T A I N E R   M O D I F I E R S
+///
+////////////////////////////////////////////////////////////////////////////////
+
+/// assign()
+///
+/// - Invalidates all iterators, including the past-the-end iterator for all
+///   container types.
+
+void list_assign(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = L.cend();
+  L.assign(10, n);
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+}
+
+void vector_assign(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = V.cend();
+  V.assign(10, n);
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+}
+
+void deque_assign(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = D.cend();
+  D.assign(10, n);
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+}
+
+void forward_list_assign(std::forward_list<int> &FL, int n) {
+  auto i0 = FL.cbegin(), i1 = FL.cend();
+  FL.assign(10, n);
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+}
+
+/// clear()
+///
+/// - Invalidates all iterators, including the past-the-end iterator for all
+///   container types.
+
+void list_clear(std::list<int> &L) {
+  auto i0 = L.cbegin(), i1 = L.cend();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  L.clear();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+}
+
+void vector_clear(std::vector<int> &V) {
+  auto i0 = V.cbegin(), i1 = V.cend();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  V.clear();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+}
+
+void deque_clear(std::deque<int> &D) {
+  auto i0 = D.cbegin(), i1 = D.cend();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  D.clear();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+}
+
+void forward_list_clear(std::forward_list<int> &FL) {
+  auto i0 = FL.cbegin(), i1 = FL.cend();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  FL.clear();
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+}
+
+/// push_back()
+///
+/// - Design decision: extends containers to the ->RIGHT-> (i.e. the
+///   past-the-end position of the container is incremented).
+///
+/// - Iterator invalidation rules depend the container type.
+
+/// std::list-like containers: No iterators are invalidated.
+
+void list_push_back(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  L.push_back(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}} FIXME: Should be $L.end() + 1
+}
+
+/// std::vector-like containers: The past-the-end iterator is invalidated.
+
+void vector_push_back(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  V.push_back(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}}
+}
+
+/// std::deque-like containers: All iterators, including the past-the-end
+///                             iterator, are invalidated.
+
+void deque_push_back(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  D.push_back(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+  clang_analyzer_express(clang_analyzer_container_end(D)); // expected-warning{{$D.end()}} FIXME: Should be $D.end() + 1 (to correctly track the container's size)
+}
+
+/// emplace_back()
+///
+/// - Design decision: extends containers to the ->RIGHT-> (i.e. the
+///   past-the-end position of the container is incremented).
+///
+/// - Iterator invalidation rules depend the container type.
+
+/// std::list-like containers: No iterators are invalidated.
+
+void list_emplace_back(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  L.emplace_back(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}  FIXME: Should be $L.end() + 1
+}
+
+/// std::vector-like containers: The past-the-end iterator is invalidated.
+
+void vector_emplace_back(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  V.emplace_back(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}}
+}
+
+/// std::deque-like containers: All iterators, including the past-the-end
+///                             iterator, are invalidated.
+
+void deque_emplace_back(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  D.emplace_back(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+  clang_analyzer_express(clang_analyzer_container_end(D)); // expected-warning{{$D.end()}}  FIXME: Should be $D.end() + 1 (to correctly track the container's size)
+}
+
+/// pop_back()
+///
+/// - Design decision: shrinks containers to the <-LEFT<- (i.e. the
+///   past-the-end position of the container is decremented).
+///
+/// - Iterator invalidation rules depend the container type.
+
+/// std::list-like containers: Iterators to the last element are invalidated.
+
+void list_pop_back(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  L.pop_back();
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}  FIXME: Should be $L.end() - 1
+}
+
+/// std::vector-like containers: Iterators to the last element, as well as the
+///                              past-the-end iterator, are invalidated.
+
+void vector_pop_back(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  V.pop_back();
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(V)); // expected-warning{{$V.end() - 1}}
+}
+
+/// std::deque-like containers: Iterators to the last element are invalidated.
+///                             The past-the-end iterator is also invalidated.
+///                             Other iterators are not affected.
+
+void deque_pop_back(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  D.pop_back();
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$D.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(D)); // expected-warning{{$D.end() - 1}}
+}
+
+/// push_front()
+///
+/// - Design decision: extends containers to the <-LEFT<- (i.e. the first
+///                    position of the container is decremented).
+///
+/// - Iterator invalidation rules depend the container type.
+
+/// std::list-like containers: No iterators are invalidated.
+
+void list_push_front(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  L.push_front(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}}
+}
+
+/// std::deque-like containers: All iterators, including the past-the-end
+///                             iterator, are invalidated.
+
+void deque_push_front(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  D.push_front(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin() - 1 (to correctly track the container's size)
+
+  clang_analyzer_express(clang_analyzer_container_end(D)); // expected-warning{{$D.end()}}
+}
+
+/// std::forward_list-like containers: No iterators are invalidated.
+
+void forward_list_push_front(std::forward_list<int> &FL, int n) {
+  auto i0 = FL.cbegin(), i1 = FL.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+
+  FL.push_front(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}}
+}
+
+/// emplace_front()
+///
+/// - Design decision: extends containers to the <-LEFT<- (i.e. the first
+///                    position of the container is decremented).
+///
+/// - Iterator invalidation rules depend the container type.
+
+/// std::list-like containers: No iterators are invalidated.
+
+void list_emplace_front(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  L.emplace_front(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}}
+}
+
+/// std::deque-like containers: All iterators, including the past-the-end
+///                             iterator, are invalidated.
+
+void deque_emplace_front(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  D.emplace_front(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin - 1 (to correctly track the container's size)
+
+  clang_analyzer_express(clang_analyzer_container_end(D)); // expected-warning{{$D.end()}}
+}
+
+/// std::forward_list-like containers: No iterators are invalidated.
+
+void forward_list_emplace_front(std::forward_list<int> &FL, int n) {
+  auto i0 = FL.cbegin(), i1 = FL.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+
+  FL.emplace_front(n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}}
+}
+
+/// pop_front()
+///
+/// - Design decision: shrinks containers to the ->RIGHT-> (i.e. the first
+///   position of the container is incremented).
+///
+/// - Iterator invalidation rules depend the container type.
+
+/// std::list-like containers: Iterators to the first element are invalidated.
+
+void list_pop_front(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  L.pop_front();
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+}
+
+/// std::deque-like containers: Iterators to the first element are invalidated.
+///                             Other iterators are not affected.
+
+void deque_pop_front(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  D.pop_front();
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$D.begin() + 1}}
+
+  clang_analyzer_express(clang_analyzer_container_end(D)); // expected-warning{{$D.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$D.end()}}
+}
+
+/// std::forward_list-like containers: Iterators to the first element are
+///                                    invalidated.
+
+void forward_list_pop_front(std::list<int> &FL, int n) {
+  auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+
+  FL.pop_front();
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin() + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.begin() + 1}}
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}}
+}
+
+/// insert()
+///
+/// - Design decision: shifts positions to the <-LEFT<- (i.e. all iterator
+///                    ahead of the insertion point are decremented; if the
+///                    relation between the insertion point and the first
+///                    position of the container is known, the first position
+///                    of the container is also decremented).
+///
+/// - Iterator invalidation rules depend the container type.
+
+/// std::list-like containers: No iterators are invalidated.
+
+void list_insert_begin(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i2 = L.insert(i0, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}}
+}
+
+void list_insert_behind_begin(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i3 = L.insert(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin()
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+}
+
+template <typename Iter> Iter return_any_iterator(const Iter &It);
+
+void list_insert_unknown(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = return_any_iterator(L.cbegin()), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = L.insert(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+}
+
+void list_insert_ahead_of_end(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i3 = L.insert(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2
+}
+
+void list_insert_end(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i3 = L.insert(i2, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} FIXME: should be $L.end() - 2
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1
+}
+
+/// std::vector-like containers: Only the iterators before the insertion point
+///                              remain valid. The past-the-end iterator is also
+///                              invalidated.
+
+void vector_insert_begin(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i2 = V.insert(i0, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $V.begin() - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); // FIXME: expect warning $V.end()
+}
+
+void vector_insert_behind_begin(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i3 = V.insert(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin()
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); // FIXME: expect warning $V.end()
+}
+
+void vector_insert_unknown(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = return_any_iterator(V.cbegin()), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = V.insert(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME expect warning $V.end()
+}
+
+void vector_insert_ahead_of_end(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i3 = V.insert(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME: expect warning $V.end() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2
+}
+
+void vector_insert_end(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i3 = V.insert(i2, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME: expect warning $V.end()
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} FIXME: Should be $V.end() - 2
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1
+}
+
+/// std::deque-like containers: All iterators, including the past-the-end
+///                             iterator, are invalidated.
+
+void deque_insert_begin(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i2 = D.insert(i0, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin() - 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $D.begin() - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+}
+
+void deque_insert_behind_begin(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i3 = D.insert(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin - 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+}
+
+void deque_insert_unknown(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = return_any_iterator(D.cbegin()), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = D.insert(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+}
+
+void deque_insert_ahead_of_end(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i3 = D.insert(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 2
+}
+
+void deque_insert_end(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i3 = D.insert(i2, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 1
+}
+
+/// insert_after()   [std::forward_list-like containers]
+///
+/// - Design decision: shifts positions to the ->RIGHT-> (i.e. all iterator
+///                    ahead of the insertion point are incremented; if the
+///                    relation between the insertion point and the past-the-end
+///                    position of the container is known, the first position of
+///                    the container is also incremented).
+///
+/// - No iterators are invalidated.
+
+void forward_list_insert_after_begin(std::forward_list<int> &FL, int n) {
+  auto i0 = FL.cbegin(), i1 = FL.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+
+  auto i2 = FL.insert_after(i0, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}}
+}
+
+void forward_list_insert_after_behind_begin(std::forward_list<int> &FL, int n) {
+  auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+
+  auto i3 = FL.insert_after(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.begin() + 1}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}}
+}
+
+void forward_list_insert_after_unknown(std::forward_list<int> &FL, int n) {
+  auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = FL.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = FL.insert_after(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}}
+}
+
+/// emplace()
+///
+/// - Design decision: shifts positions to the <-LEFT<- (i.e. all iterator
+///                    ahead of the emplacement point are decremented; if the
+///                    relation between the emplacement point and the first
+///                    position of the container is known, the first position
+///                    of the container is also decremented).
+///
+/// - Iterator invalidation rules depend the container type.
+
+/// std::list-like containers: No iterators are invalidated.
+
+void list_emplace_begin(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i2 = L.emplace(i0, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $L.begin() - 1
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end()}}
+}
+
+void list_emplace_behind_begin(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i3 = L.emplace(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin()
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+}
+
+template <typename Iter> Iter return_any_iterator(const Iter &It);
+
+void list_emplace_unknown(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = return_any_iterator(L.cbegin()), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = L.emplace(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+}
+
+void list_emplace_ahead_of_end(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i3 = L.emplace(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2
+}
+
+void list_emplace_end(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i3 = L.emplace(i2, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.end() - 1}} FIXME: should be $L.end() - 2
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1
+}
+
+/// std::vector-like containers: Only the iterators before the emplacement point
+///                              remain valid. The past-the-end iterator is also
+///                              invalidated.
+
+void vector_emplace_begin(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i2 = V.emplace(i0, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $V.begin() - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); // FIXME: expect warning $V.end()
+}
+
+void vector_emplace_behind_begin(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i3 = V.emplace(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() - 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); // FIXME: expect -warning $V.begin()
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); // FIXME: expect warning $V.end()
+}
+
+void vector_emplace_unknown(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = return_any_iterator(V.cbegin()), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = V.emplace(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME expect warning $V.end()
+}
+
+void vector_emplace_ahead_of_end(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i3 = V.emplace(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME: expect warning $V.end() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2
+}
+
+void vector_emplace_end(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i3 = V.emplace(i2, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME: expect warning $V.end()
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}} FIXME: Should be $V.end() - 2
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 1
+}
+
+/// std::deque-like containers: All iterators, including the past-the-end
+///                             iterator, are invalidated.
+
+void deque_emplace_begin(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i2 = D.emplace(i0, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin() - 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $D.begin() - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+}
+
+void deque_emplace_behind_begin(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i3 = D.emplace(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin - 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+}
+
+void deque_emplace_unknown(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = return_any_iterator(D.cbegin()), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = D.emplace(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 - 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+}
+
+void deque_emplace_ahead_of_end(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i3 = D.emplace(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 2
+}
+
+void deque_emplace_end(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i3 = D.emplace(i2, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end() - 1
+}
+
+/// emplace_after()   [std::forward_list-like containers]
+///
+/// - Design decision: shifts positions to the ->RIGHT-> (i.e. all iterator
+///                    ahead of the emplacement point are incremented; if the
+///                    relation between the emplacement point and the
+///                    past-the-end position of the container is known, the
+///                    first position of the container is also incremented).
+///
+/// - No iterators are invalidated.
+
+void forward_list_emplace_after_begin(std::forward_list<int> &FL, int n) {
+  auto i0 = FL.cbegin(), i1 = FL.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+
+  auto i2 = FL.emplace_after(i0, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i2)); FIXME: expect warning $FL.begin() + 1
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.end()}}
+}
+
+void forward_list_emplace_after_behind_begin(std::forward_list<int> &FL,
+                                             int n) {
+  auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+
+  auto i3 = FL.emplace_after(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$FL.begin() + 1}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $FL.begin() + 2
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}}
+}
+
+void forward_list_emplace_after_unknown(std::forward_list<int> &FL, int n) {
+  auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = FL.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = FL.emplace_after(i1, n);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.end()}}
+}
+
+/// erase()
+///
+/// - Design decision: shifts positions to the ->RIGHT-> (i.e. all iterator
+///                    ahead of the ereased element are incremented; if the
+///                    relation between the position of the erased element
+///                    and the first position of the container is known, the
+///                    first position of the container is also incremented).
+///
+/// - Iterator invalidation rules depend the container type.
+
+/// std::list-like containers: Iterators to the erased element are invalidated.
+///                            Other iterators are not affected.
+
+void list_erase_begin(std::list<int> &L) {
+  auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i3 = L.erase(i0);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}} FIXME: Should be$L.begin() + 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$L.begin() + 1}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 1
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+}
+
+void list_erase_behind_begin(std::list<int> &L, int n) {
+  auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i3 = L.erase(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() + 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}} FIXME: Should be $L.begin() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 2
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+}
+
+void list_erase_unknown(std::list<int> &L) {
+  auto i0 = L.cbegin(), i1 = return_any_iterator(L.cbegin()), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = L.erase(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+}
+
+void list_erase_ahead_of_end(std::list<int> &L) {
+  auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
+
+  auto i3 = L.erase(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(L)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+
+  clang_analyzer_express(clang_analyzer_container_end(L)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end()
+}
+
+/// std::vector-like containers: Invalidates iterators at or after the point of
+///                              the erase, including the past-the-end iterator.
+
+void vector_erase_begin(std::vector<int> &V) {
+  auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i3 = V.erase(i0);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.begin() + 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME: expect warning $V.end()
+}
+
+void vector_erase_behind_begin(std::vector<int> &V, int n) {
+  auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i3 = V.erase(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() + 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.begin() + 2
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME: expect warning $V.end()
+}
+
+void vector_erase_unknown(std::vector<int> &V) {
+  auto i0 = V.cbegin(), i1 = return_any_iterator(V.cbegin()), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = V.erase(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME: expect warning $V.end()
+}
+
+void vector_erase_ahead_of_end(std::vector<int> &V) {
+  auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
+
+  auto i3 = V.erase(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(V)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(V)); FIXME: expect warning $V.end()
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end()
+}
+
+/// std::deque-like containers: All iterators are invalidated, unless the erased
+///                             element is at the end or the beginning of the
+///                             container, in which case only the iterators to
+///                             the erased element are invalidated. The
+///                             past-the-end iterator is also invalidated unless
+///                             the erased element is at the beginning of the
+///                             container and the last element is not erased.
+
+void deque_erase_begin(std::deque<int> &D) {
+  auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i3 = D.erase(i0);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() + 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning{{$D.end()
+}
+
+void deque_erase_behind_begin(std::deque<int> &D, int n) {
+  auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i3 = D.erase(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}} FIXME: Should be $D.begin() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.begin() + 2
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+}
+
+void deque_erase_unknown(std::deque<int> &D) {
+  auto i0 = D.cbegin(), i1 = return_any_iterator(D.cbegin()), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i3 = D.erase(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+}
+
+void deque_erase_ahead_of_end(std::deque<int> &D) {
+  auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
+
+  auto i3 = D.erase(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(D)); // expected-warning{{$D.begin()}}
+
+  // clang_analyzer_express(clang_analyzer_container_end(D)); FIXME: expect warning $D.end()
+  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $D.end()
+}
+
+/// erase_after()   [std::forward_list-like containers]
+///
+/// - Design decision: shifts positions to the <-LEFT<- (i.e. all iterator
+///                    begind of the ereased element are decremented; if the
+///                    relation between the position of the erased element
+///                    and the past-the-end position of the container is known,
+///                    the past-the-end position of the container is also
+///                    decremented).
+///
+/// - Iterators to the erased element are invalidated. Other iterators are not
+///   affected.
+
+
+void forward_list_erase_after_begin(std::forward_list<int> &FL) {
+  auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = i1, i3 = FL.cend();
+  ++i2;
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+
+  auto i4 = FL.erase_after(i0);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.begin() + 2}} FIXME: Should be $FL.begin() + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i4)); FIXME: expect warning $FL.begin() + 1
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$FL.end()}}
+}
+
+void forward_list_erase_after_unknown(std::forward_list<int> &FL) {
+  auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = i1,
+    i3 = i1, i4 = FL.cend();
+  ++i2;
+  ++i3;
+  ++i3;
+
+  clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
+  clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
+  clang_analyzer_denote(clang_analyzer_iterator_position(i1), "$i1");
+
+  auto i5 = FL.erase_after(i1);
+
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i0)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}}
+  clang_analyzer_eval(clang_analyzer_iterator_validity(i4)); //expected-warning{{TRUE}}
+
+  clang_analyzer_express(clang_analyzer_container_begin(FL)); // expected-warning{{$FL.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$i1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 2}} FIXME: Should be $i1 + 1
+  // clang_analyzer_express(clang_analyzer_iterator_position(i5)); FIXME: expect warning $i1 + 1
+
+  clang_analyzer_express(clang_analyzer_container_end(FL)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i4)); // expected-warning{{$FL.end()}}
+}
+
+struct simple_iterator_base {
+  simple_iterator_base();
+  simple_iterator_base(const simple_iterator_base& rhs);
+  simple_iterator_base &operator=(const simple_iterator_base& rhs);
+  virtual ~simple_iterator_base();
+  bool friend operator==(const simple_iterator_base &lhs,
+                         const simple_iterator_base &rhs);
+  bool friend operator!=(const simple_iterator_base &lhs,
+                         const simple_iterator_base &rhs);
+private:
+  int *ptr;
+};
+
+struct simple_derived_iterator: public simple_iterator_base {
+  int& operator*();
+  int* operator->();
+  simple_iterator_base &operator++();
+  simple_iterator_base operator++(int);
+  simple_iterator_base &operator--();
+  simple_iterator_base operator--(int);
+};
+
+struct simple_container {
+  typedef simple_derived_iterator iterator;
+
+  iterator begin();
+  iterator end();
+};
+
+void good_derived(simple_container c) {
+  auto i0 = c.end();
+  
+  if (i0 != c.end()) {
+    clang_analyzer_warnIfReached();
+  }
+}
+
+void iter_
diff (std::vector<int> &V) {
+  auto i0 = V.begin(), i1 = V.end();
+  ptr
diff _t len = i1 - i0; // no-crash
+}
+
+void deferred_assumption(std::vector<int> &V, int e) {
+  const auto first = V.begin();
+  const auto comp1 = (first != V.end()), comp2 = (first == V.end());
+  if (comp1) {
+    clang_analyzer_eval(clang_analyzer_container_end(V) ==
+                        clang_analyzer_iterator_position(first)); // expected-warning at -1{{FALSE}}
+  }
+}
+
+void loop(std::vector<int> &V, int e) {
+  auto start = V.begin();
+  while (true) {
+    auto item = std::find(start, V.end(), e);
+    if (item == V.end())
+      break;
+
+    clang_analyzer_eval(clang_analyzer_container_end(V) ==
+                        clang_analyzer_iterator_position(item)); // expected-warning at -1{{FALSE}}
+  }
+}
+
+template <typename InputIterator, typename T>
+InputIterator nonStdFind(InputIterator first, InputIterator last,
+                         const T &val) {
+  for (auto i = first; i != last; ++i) {
+    if (*i == val) {
+      return i;
+    }
+  }
+  return last;
+}
+
+void non_std_find(std::vector<int> &V, int e) {
+  auto first = nonStdFind(V.begin(), V.end(), e);
+  clang_analyzer_eval(clang_analyzer_container_end(V) ==
+                      clang_analyzer_iterator_position(first)); // expected-warning at -1{{FALSE}} expected-warning at -1{{TRUE}}
+  if (V.end() != first) {
+      clang_analyzer_eval(clang_analyzer_container_end(V) ==
+                        clang_analyzer_iterator_position(first)); // expected-warning at -1{{FALSE}} expected-warning at -1 0-1{{TRUE}} FIXME: should only expect FALSE in every case
+  }
+}

diff  --git a/clang/test/Analysis/iterator-range.cpp b/clang/test/Analysis/iterator-range.cpp
index 93f69e47f563..71af17a1f3d0 100644
--- a/clang/test/Analysis/iterator-range.cpp
+++ b/clang/test/Analysis/iterator-range.cpp
@@ -5,240 +5,376 @@
 
 void clang_analyzer_warnIfReached();
 
-void simple_good_end(const std::vector<int> &v) {
-  auto i = v.end();
-  if (i != v.end()) {
-    clang_analyzer_warnIfReached();
-    *i; // no-warning
-  }
+// Dereference - operator*()
+
+void deref_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  *i; // no-warning
+}
+
+void deref_begind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  *i; // no-warning
+}
+
+template <typename Iter> Iter return_any_iterator(const Iter &It);
+
+void deref_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  *i; // no-warning
 }
 
-void simple_good_end_negated(const std::vector<int> &v) {
-  auto i = v.end();
-  if (!(i == v.end())) {
-    clang_analyzer_warnIfReached();
-    *i; // no-warning
-  }
+void deref_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  *i; // no-warning
 }
 
-void simple_bad_end(const std::vector<int> &v) {
-  auto i = v.end();
+void deref_end(const std::vector<int> &V) {
+  auto i = V.end();
   *i; // expected-warning{{Past-the-end iterator dereferenced}}
-  clang_analyzer_warnIfReached();
 }
 
-void copy(const std::vector<int> &v) {
-  auto i1 = v.end();
-  auto i2 = i1;
-  *i2; // expected-warning{{Past-the-end iterator dereferenced}}
+// Prefix increment - operator++()
+
+void incr_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  ++i; // no-warning
+}
+
+void incr_behind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  ++i; // no-warning
+}
+
+void incr_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  ++i; // no-warning
+}
+
+void incr_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  ++i; // no-warning
+}
+
+void incr_end(const std::vector<int> &V) {
+  auto i = V.end();
+  ++i; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
+}
+
+// Postfix increment - operator++(int)
+
+void begin_incr(const std::vector<int> &V) {
+  auto i = V.begin();
+  i++; // no-warning
+}
+
+void behind_begin_incr(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  i++; // no-warning
+}
+
+void unknown_incr(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  i++; // no-warning
+}
+
+void ahead_of_end_incr(const std::vector<int> &V) {
+  auto i = --V.end();
+  i++; // no-warning
+}
+
+void end_incr(const std::vector<int> &V) {
+  auto i = V.end();
+  i++; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
+}
+
+// Prefix decrement - operator--()
+
+void decr_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  --i; // expected-warning{{Iterator decremented ahead of its valid range}}
+}
+
+void decr_behind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  --i; // no-warning
+}
+
+void decr_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  --i; // no-warning
+}
+
+void decr_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  --i; // no-warning
+}
+
+void decr_end(const std::vector<int> &V) {
+  auto i = V.end();
+  --i; // no-warning
+}
+
+// Postfix decrement - operator--(int)
+
+void begin_decr(const std::vector<int> &V) {
+  auto i = V.begin();
+  i--; // expected-warning{{Iterator decremented ahead of its valid range}}
+}
+
+void behind_begin_decr(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  i--; // no-warning
 }
 
-void decrease(const std::vector<int> &v) {
-  auto i = v.end();
+void unknown_decr(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  i--; // no-warning
+}
+
+void ahead_of_end_decr(const std::vector<int> &V) {
+  auto i = --V.end();
+  i--; // no-warning
+}
+
+void end_decr(const std::vector<int> &V) {
+  auto i = V.end();
+  i--; // no-warning
+}
+
+// Addition assignment - operator+=(int)
+
+void incr_by_2_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  i += 2; // no-warning
+}
+
+void incr_by_2_behind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  i += 2; // no-warning
+}
+
+void incr_by_2_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  i += 2; // no-warning
+}
+
+void incr_by_2_ahead_by_2_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
   --i;
-  *i; // no-warning
+  i += 2; // no-warning
 }
 
-void copy_and_decrease1(const std::vector<int> &v) {
-  auto i1 = v.end();
-  auto i2 = i1;
-  --i1;
-  *i1; // no-warning
+void incr_by_2_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
 }
 
-void copy_and_decrease2(const std::vector<int> &v) {
-  auto i1 = v.end();
-  auto i2 = i1;
-  --i1;
-  *i2; // expected-warning{{Past-the-end iterator dereferenced}}
+void incr_by_2_end(const std::vector<int> &V) {
+  auto i = V.end();
+  i += 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
 }
 
-void copy_and_increase1(const std::vector<int> &v) {
-  auto i1 = v.begin();
-  auto i2 = i1;
-  ++i1;
-  if (i1 == v.end())
-    *i2; // no-warning
+// Addition - operator+(int)
+
+void incr_by_2_copy_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  auto j = i + 2; // no-warning
 }
 
-void copy_and_increase2(const std::vector<int> &v) {
-  auto i1 = v.begin();
-  auto i2 = i1;
-  ++i1;
-  if (i2 == v.end())
-    *i2; // expected-warning{{Past-the-end iterator dereferenced}}
+void incr_by_2_copy_behind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  auto j = i + 2; // no-warning
 }
 
-void copy_and_increase3(const std::vector<int> &v) {
-  auto i1 = v.begin();
-  auto i2 = i1;
-  ++i1;
-  if (v.end() == i2)
-    *i2; // expected-warning{{Past-the-end iterator dereferenced}}
+void incr_by_2_copy_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  auto j = i + 2; // no-warning
 }
 
-template <class InputIterator, class T>
-InputIterator nonStdFind(InputIterator first, InputIterator last,
-                         const T &val) {
-  for (auto i = first; i != last; ++i) {
-    if (*i == val) {
-      return i;
-    }
-  }
-  return last;
+void incr_by_2_copy_ahead_by_2_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  --i;
+  auto j = i + 2; // no-warning
 }
 
-void good_non_std_find(std::vector<int> &V, int e) {
-  auto first = nonStdFind(V.begin(), V.end(), e);
-  if (V.end() != first)
-    *first; // no-warning
+void incr_by_2_copy_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
 }
 
-void bad_non_std_find(std::vector<int> &V, int e) {
-  auto first = nonStdFind(V.begin(), V.end(), e);
-  *first; // expected-warning{{Past-the-end iterator dereferenced}}
+void incr_by_2_copy_end(const std::vector<int> &V) {
+  auto i = V.end();
+  auto j = i + 2; // expected-warning{{Iterator incremented behind the past-the-end iterator}}
 }
 
-void tricky(std::vector<int> &V, int e) {
-  const auto first = V.begin();
-  const auto comp1 = (first != V.end()), comp2 = (first == V.end());
-  if (comp1)
-    *first; // no-warning
+// Subtraction assignment - operator-=(int)
+
+void decr_by_2_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}}
 }
 
-void loop(std::vector<int> &V, int e) {
-  auto start = V.begin();
-  while (true) {
-    auto item = std::find(start, V.end(), e);
-    if (item == V.end())
-      break;
-    *item;          // no-warning
-    start = ++item; // no-warning
-  }
+void decr_by_2_behind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  i -= 2; // expected-warning{{Iterator decremented ahead of its valid range}}
 }
 
-void good_push_back(std::list<int> &L, int n) {
-  auto i0 = --L.cend();
-  L.push_back(n);
-  *++i0; // no-warning
+void decr_by_2_behind_begin_by_2(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  ++i;
+  i -= 2; // no-warning
 }
 
-void bad_push_back(std::list<int> &L, int n) {
-  auto i0 = --L.cend();
-  L.push_back(n);
-  ++i0;
-  *++i0; // expected-warning{{Past-the-end iterator dereferenced}}
+void decr_by_2_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  i -= 2; // no-warning
 }
 
-void good_pop_back(std::list<int> &L, int n) {
-  auto i0 = --L.cend(); --i0;
-  L.pop_back();
-  *i0; // no-warning
+void decr_by_2_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  i -= 2; // no-warning
 }
 
-void bad_pop_back(std::list<int> &L, int n) {
-  auto i0 = --L.cend(); --i0;
-  L.pop_back();
-  *++i0; // expected-warning{{Past-the-end iterator dereferenced}}
+void decr_by_2_end(const std::vector<int> &V) {
+  auto i = V.end();
+  i -= 2; // no-warning
 }
 
-void good_push_front(std::list<int> &L, int n) {
-  auto i0 = L.cbegin();
-  L.push_front(n);
-  *--i0; // no-warning
+// Subtraction - operator-(int)
+
+void decr_by_2_copy_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}}
 }
 
-void bad_push_front(std::list<int> &L, int n) {
-  auto i0 = L.cbegin();
-  L.push_front(n);
-  --i0;
-  --i0; // expected-warning{{Iterator decremented ahead of its valid range}}
+void decr_by_2_copy_behind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  auto j = i - 2; // expected-warning{{Iterator decremented ahead of its valid range}}
 }
 
-void good_pop_front(std::list<int> &L, int n) {
-  auto i0 = ++L.cbegin();
-  L.pop_front();
-  *i0; // no-warning
+void decr_by_2_copy_behind_begin_by_2(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  ++i;
+  auto j = i - 2; // no-warning
 }
 
-void bad_pop_front(std::list<int> &L, int n) {
-  auto i0 = ++L.cbegin();
-  L.pop_front();
-  --i0; // expected-warning{{Iterator decremented ahead of its valid range}}
+void decr_by_2_copy_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  auto j = i - 2; // no-warning
 }
 
-void bad_move(std::list<int> &L1, std::list<int> &L2) {
-  auto i0 = --L2.cend();
-  L1 = std::move(L2);
-  *++i0; // expected-warning{{Past-the-end iterator dereferenced}}
+void decr_by_2_copy_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  auto j = i - 2; // no-warning
 }
 
-void bad_move_push_back(std::list<int> &L1, std::list<int> &L2, int n) {
-  auto i0 = --L2.cend();
-  L2.push_back(n);
-  L1 = std::move(L2);
-  ++i0;
-  *++i0; // expected-warning{{Past-the-end iterator dereferenced}}
+void decr_by_2_copy_end(const std::vector<int> &V) {
+  auto i = V.end();
+  auto j = i - 2; // no-warning
 }
 
-void good_incr_begin(const std::list<int> &L) {
-  auto i0 = L.begin();
-  ++i0; // no-warning
+//
+// Subscript - operator[](int)
+//
+
+// By zero
+
+void subscript_zero_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  auto j = i[0]; // no-warning
 }
 
-void bad_decr_begin(const std::list<int> &L) {
-  auto i0 = L.begin();
-  --i0;  // expected-warning{{Iterator decremented ahead of its valid range}}
+void subscript_zero_behind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  auto j = i[0]; // no-warning
 }
 
-void good_decr_end(const std::list<int> &L) {
-  auto i0 = L.end();
-  --i0; // no-warning
+void subscript_zero_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  auto j = i[0]; // no-warning
 }
 
-void bad_incr_end(const std::list<int> &L) {
-  auto i0 = L.end();
-  ++i0;  // expected-warning{{Iterator incremented behind the past-the-end iterator}}
+void subscript_zero_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  auto j = i[0]; // no-warning
 }
 
-struct simple_iterator_base {
-  simple_iterator_base();
-  simple_iterator_base(const simple_iterator_base& rhs);
-  simple_iterator_base &operator=(const simple_iterator_base& rhs);
-  virtual ~simple_iterator_base();
-  bool friend operator==(const simple_iterator_base &lhs,
-                         const simple_iterator_base &rhs);
-  bool friend operator!=(const simple_iterator_base &lhs,
-                         const simple_iterator_base &rhs);
-private:
-  int *ptr;
-};
+void subscript_zero_end(const std::vector<int> &V) {
+  auto i = V.end();
+  auto j = i[0]; // expected-warning{{Past-the-end iterator dereferenced}}
+}
 
-struct simple_derived_iterator: public simple_iterator_base {
-  int& operator*();
-  int* operator->();
-  simple_iterator_base &operator++();
-  simple_iterator_base operator++(int);
-  simple_iterator_base &operator--();
-  simple_iterator_base operator--(int);
-};
+// By negative number
 
-struct simple_container {
-  typedef simple_derived_iterator iterator;
+void subscript_negative_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  auto j = i[-1]; // no-warning FIXME: expect warning Iterator decremented ahead of its valid range
+}
+
+void subscript_negative_behind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  auto j = i[-1]; // no-warning
+}
+
+void subscript_negative_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  auto j = i[-1]; // no-warning
+}
+
+void subscript_negative_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  auto j = i[-1]; // no-warning
+}
+
+void subscript_negative_end(const std::vector<int> &V) {
+  auto i = V.end();
+  auto j = i[-1]; // // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect no warning
+}
+
+// By positive number
+
+void subscript_positive_begin(const std::vector<int> &V) {
+  auto i = V.begin();
+  auto j = i[1]; // no-warning
+}
+
+void subscript_positive_behind_begin(const std::vector<int> &V) {
+  auto i = ++V.begin();
+  auto j = i[1]; // no-warning
+}
 
-  iterator begin();
-  iterator end();
+void subscript_positive_unknown(const std::vector<int> &V) {
+  auto i = return_any_iterator(V.begin());
+  auto j = i[1]; // no-warning
+}
+
+void subscript_positive_ahead_of_end(const std::vector<int> &V) {
+  auto i = --V.end();
+  auto j = i[1]; // no-warning FIXME: expected warning Past-the-end iterator dereferenced
+}
+
+void subscript_positive_end(const std::vector<int> &V) {
+  auto i = V.end();
+  auto j = i[1]; // expected-warning{{Past-the-end iterator dereferenced}} FIXME: expect warning Iterator incremented behind the past-the-end iterator
+}
+
+//
+// Structure member dereference operators
+//
+
+struct S {
+  int n;
 };
 
-void good_derived(simple_container c) {
-  auto i0 = c.end();
-  if (i0 != c.end()) {
-    clang_analyzer_warnIfReached();
-    *i0; // no-warning
-  }
+// Member dereference - operator->()
+
+void arrow_deref_begin(const std::vector<S> &V) {
+  auto i = V.begin();
+  int n = i->n; // no-warning
 }
 
-void iter_
diff (std::vector<int> &V) {
-  auto i0 = V.begin(), i1 = V.end();
-  ptr
diff _t len = i1 - i0; // no-crash
+void arrow_deref_end(const std::vector<S> &V) {
+  auto i = V.end();
+  int n = i->n; //  expected-warning{{Past-the-end iterator dereferenced}}
 }

diff  --git a/clang/test/Analysis/mismatched-iterator.cpp b/clang/test/Analysis/mismatched-iterator.cpp
index 26a71c399c70..c58d14d72fda 100644
--- a/clang/test/Analysis/mismatched-iterator.cpp
+++ b/clang/test/Analysis/mismatched-iterator.cpp
@@ -3,203 +3,118 @@
 
 #include "Inputs/system-header-simulator-cxx.h"
 
-void good_insert1(std::vector<int> &v, int n) {
-  v.insert(v.cbegin(), n); // no-warning
+void good_insert1(std::vector<int> &V, int n) {
+  V.insert(V.cbegin(), n); // no-warning
 }
 
-
-void good_insert2(std::vector<int> &v, int len, int n) {
-  v.insert(v.cbegin(), len, n); // no-warning
-}
-
-void good_insert3(std::vector<int> &v1, std::vector<int> &v2) {
-  v1.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // no-warning
-}
-
-void good_insert4(std::vector<int> &v, int len, int n) {
-  v.insert(v.cbegin(), {n-1, n, n+1}); // no-warning
-}
-
-void good_insert_find(std::vector<int> &v, int n, int m) {
-  auto i = std::find(v.cbegin(), v.cend(), n);
-  v.insert(i, m); // no-warning
-}
-
-void good_erase1(std::vector<int> &v) {
-  v.erase(v.cbegin()); // no-warning
-}
-
-void good_erase2(std::vector<int> &v) {
-  v.erase(v.cbegin(), v.cend()); // no-warning
-}
-
-void good_emplace(std::vector<int> &v, int n) {
-  v.emplace(v.cbegin(), n); // no-warning
-}
-
-void good_ctor(std::vector<int> &v) {
-  std::vector<int> new_v(v.cbegin(), v.cend()); // no-warning
-}
-
-void good_find(std::vector<int> &v, int n) {
-  std::find(v.cbegin(), v.cend(), n); // no-warning
-}
-
-void good_find_first_of(std::vector<int> &v1, std::vector<int> &v2) {
-  std::find_first_of(v1.cbegin(), v1.cend(), v2.cbegin(), v2.cend()); // no-warning
-}
-
-void good_copy(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  std::copy(v1.cbegin(), v1.cend(), v2.begin()); // no-warning
-}
-
-void good_move_find1(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  auto i0 = v2.cbegin();
-  v1 = std::move(v2);
-  std::find(i0, v1.cend(), n); // no-warning
-}
-
-void bad_insert1(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  v2.insert(v1.cbegin(), n); // expected-warning{{Container accessed using foreign iterator argument}}
-}
-
-void bad_insert2(std::vector<int> &v1, std::vector<int> &v2, int len, int n) {
-  v2.insert(v1.cbegin(), len, n); // expected-warning{{Container accessed using foreign iterator argument}}
-}
-
-void bad_insert3(std::vector<int> &v1, std::vector<int> &v2) {
-  v2.insert(v1.cbegin(), v2.cbegin(), v2.cend()); // expected-warning{{Container accessed using foreign iterator argument}}
-  v1.insert(v1.cbegin(), v1.cbegin(), v2.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
-  v1.insert(v1.cbegin(), v2.cbegin(), v1.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
+void good_insert2(std::vector<int> &V, int len, int n) {
+  V.insert(V.cbegin(), len, n); // no-warning
 }
 
-void bad_insert4(std::vector<int> &v1, std::vector<int> &v2, int len, int n) {
-  v2.insert(v1.cbegin(), {n-1, n, n+1}); // expected-warning{{Container accessed using foreign iterator argument}}
+void good_insert3(std::vector<int> &V1, std::vector<int> &V2) {
+  V1.insert(V1.cbegin(), V2.cbegin(), V2.cend()); // no-warning
 }
 
-void bad_erase1(std::vector<int> &v1, std::vector<int> &v2) {
-  v2.erase(v1.cbegin()); // expected-warning{{Container accessed using foreign iterator argument}}
+void good_insert4(std::vector<int> &V, int len, int n) {
+  V.insert(V.cbegin(), {n-1, n, n+1}); // no-warning
 }
 
-void bad_erase2(std::vector<int> &v1, std::vector<int> &v2) {
-  v2.erase(v2.cbegin(), v1.cend()); // expected-warning{{Container accessed using foreign iterator argument}}
-  v2.erase(v1.cbegin(), v2.cend()); // expected-warning{{Container accessed using foreign iterator argument}}
-  v2.erase(v1.cbegin(), v1.cend()); // expected-warning{{Container accessed using foreign iterator argument}}
+void good_insert_find(std::vector<int> &V, int n, int m) {
+  auto i = std::find(V.cbegin(), V.cend(), n);
+  V.insert(i, m); // no-warning
 }
 
-void bad_emplace(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  v2.emplace(v1.cbegin(), n); // expected-warning{{Container accessed using foreign iterator argument}}
+void good_erase1(std::vector<int> &V) {
+  V.erase(V.cbegin()); // no-warning
 }
 
-void good_move_find2(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  auto i0 = --v2.cend();
-  v1 = std::move(v2);
-  std::find(i0, v1.cend(), n); // no-warning
+void good_erase2(std::vector<int> &V) {
+  V.erase(V.cbegin(), V.cend()); // no-warning
 }
 
-void good_move_find3(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  auto i0 = v2.cend();
-  v1 = std::move(v2);
-  v2.push_back(n); // expected-warning{{Method called on moved-from object of type 'std::vector'}}
-  std::find(v2.cbegin(), i0, n); // no-warning
+void good_emplace(std::vector<int> &V, int n) {
+  V.emplace(V.cbegin(), n); // no-warning
 }
 
-void good_comparison(std::vector<int> &v) {
-  if (v.cbegin() == v.cend()) {} // no-warning
+void good_ctor(std::vector<int> &V) {
+  std::vector<int> new_v(V.cbegin(), V.cend()); // no-warning
 }
 
-void bad_ctor(std::vector<int> &v1, std::vector<int> &v2) {
-  std::vector<int> new_v(v1.cbegin(), v2.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
+void good_find(std::vector<int> &V, int n) {
+  std::find(V.cbegin(), V.cend(), n); // no-warning
 }
 
-void bad_find(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  std::find(v1.cbegin(), v2.cend(), n); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
+void good_find_first_of(std::vector<int> &V1, std::vector<int> &V2) {
+  std::find_first_of(V1.cbegin(), V1.cend(), V2.cbegin(), V2.cend()); // no-warning
 }
 
-void bad_find_first_of(std::vector<int> &v1, std::vector<int> &v2) {
-  std::find_first_of(v1.cbegin(), v2.cend(), v2.cbegin(), v2.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
-  std::find_first_of(v1.cbegin(), v1.cend(), v2.cbegin(), v1.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
+void good_copy(std::vector<int> &V1, std::vector<int> &V2, int n) {
+  std::copy(V1.cbegin(), V1.cend(), V2.begin()); // no-warning
 }
 
-void bad_move_find1(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  auto i0 = v2.cbegin();
-  v1 = std::move(v2);
-  std::find(i0, v2.cend(), n); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
-                               // expected-warning at -1{{Method called on moved-from object of type 'std::vector'}}
+void bad_insert1(std::vector<int> &V1, std::vector<int> &V2, int n) {
+  V2.insert(V1.cbegin(), n); // expected-warning{{Container accessed using foreign iterator argument}}
 }
 
-void bad_insert_find(std::vector<int> &v1, std::vector<int> &v2, int n, int m) {
-  auto i = std::find(v1.cbegin(), v1.cend(), n);
-  v2.insert(i, m); // expected-warning{{Container accessed using foreign iterator argument}}
+void bad_insert2(std::vector<int> &V1, std::vector<int> &V2, int len, int n) {
+  V2.insert(V1.cbegin(), len, n); // expected-warning{{Container accessed using foreign iterator argument}}
 }
 
-void good_overwrite(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  auto i = v1.cbegin();
-  i = v2.cbegin();
-  v2.insert(i, n); // no-warning
+void bad_insert3(std::vector<int> &V1, std::vector<int> &V2) {
+  V2.insert(V1.cbegin(), V2.cbegin(), V2.cend()); // expected-warning{{Container accessed using foreign iterator argument}}
+  V1.insert(V1.cbegin(), V1.cbegin(), V2.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
+  V1.insert(V1.cbegin(), V2.cbegin(), V1.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
 }
 
-void bad_overwrite(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  auto i = v1.cbegin();
-  i = v2.cbegin();
-  v1.insert(i, n); // expected-warning{{Container accessed using foreign iterator argument}}
+void bad_insert4(std::vector<int> &V1, std::vector<int> &V2, int len, int n) {
+  V2.insert(V1.cbegin(), {n-1, n, n+1}); // expected-warning{{Container accessed using foreign iterator argument}}
 }
 
-template<typename Container, typename Iterator>
-bool is_cend(Container cont, Iterator it) {
-  return it == cont.cend();
+void bad_erase1(std::vector<int> &V1, std::vector<int> &V2) {
+  V2.erase(V1.cbegin()); // expected-warning{{Container accessed using foreign iterator argument}}
 }
 
-void good_empty(std::vector<int> &v) {
-  is_cend(v, v.cbegin()); // no-warning
+void bad_erase2(std::vector<int> &V1, std::vector<int> &V2) {
+  V2.erase(V2.cbegin(), V1.cend()); // expected-warning{{Container accessed using foreign iterator argument}}
+  V2.erase(V1.cbegin(), V2.cend()); // expected-warning{{Container accessed using foreign iterator argument}}
+  V2.erase(V1.cbegin(), V1.cend()); // expected-warning{{Container accessed using foreign iterator argument}}
 }
 
-void bad_empty(std::vector<int> &v1, std::vector<int> &v2) {
-  is_cend(v1, v2.cbegin()); // expected-warning at -8{{Iterators of 
diff erent containers used where the same container is expected}}
+void bad_emplace(std::vector<int> &V1, std::vector<int> &V2, int n) {
+  V2.emplace(V1.cbegin(), n); // expected-warning{{Container accessed using foreign iterator argument}}
 }
 
-void good_move(std::vector<int> &v1, std::vector<int> &v2) {
-  const auto i0 = ++v2.cbegin();
-  v1 = std::move(v2);
-  v1.erase(i0); // no-warning
+void good_comparison(std::vector<int> &V) {
+  if (V.cbegin() == V.cend()) {} // no-warning
 }
 
-void bad_move(std::vector<int> &v1, std::vector<int> &v2) {
-  const auto i0 = ++v2.cbegin();
-  v1 = std::move(v2);
-  v2.erase(i0); // expected-warning{{Container accessed using foreign iterator argument}}
-                // expected-warning at -1{{Method called on moved-from object of type 'std::vector'}}
+void bad_comparison(std::vector<int> &V1, std::vector<int> &V2) {
+  if (V1.cbegin() != V2.cend()) {} // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
 }
 
-void bad_move_find2(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  auto i0 = --v2.cend();
-  v1 = std::move(v2);
-  std::find(i0, v2.cend(), n); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
-                               // expected-warning at -1{{Method called on moved-from object of type 'std::vector'}}
+void bad_ctor(std::vector<int> &V1, std::vector<int> &V2) {
+  std::vector<int> new_v(V1.cbegin(), V2.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
 }
 
-void bad_move_find3(std::vector<int> &v1, std::vector<int> &v2, int n) {
-  auto i0 = v2.cend();
-  v1 = std::move(v2);
-  std::find(v1.cbegin(), i0, n); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
+void bad_find(std::vector<int> &V1, std::vector<int> &V2, int n) {
+  std::find(V1.cbegin(), V2.cend(), n); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
 }
 
-void bad_comparison(std::vector<int> &v1, std::vector<int> &v2) {
-  if (v1.cbegin() != v2.cend()) { // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
-    *v1.cbegin();
-  }
+void bad_find_first_of(std::vector<int> &V1, std::vector<int> &V2) {
+  std::find_first_of(V1.cbegin(), V2.cend(), V2.cbegin(), V2.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
+  std::find_first_of(V1.cbegin(), V1.cend(), V2.cbegin(), V1.cend()); // expected-warning{{Iterators of 
diff erent containers used where the same container is expected}}
 }
 
 std::vector<int> &return_vector_ref();
 
 void ignore_conjured1() {
-  std::vector<int> &v1 = return_vector_ref(), &v2 = return_vector_ref();
+  std::vector<int> &V1 = return_vector_ref(), &V2 = return_vector_ref();
 
-  v2.erase(v1.cbegin()); // no-warning
+  V2.erase(V1.cbegin()); // no-warning
 }
 
 void ignore_conjured2() {
-  std::vector<int> &v1 = return_vector_ref(), &v2 = return_vector_ref();
+  std::vector<int> &V1 = return_vector_ref(), &V2 = return_vector_ref();
 
-  if (v1.cbegin() == v2.cbegin()) {} //no-warning
+  if (V1.cbegin() == V2.cbegin()) {} //no-warning
 }


        


More information about the cfe-commits mailing list