baloghadamsoftware created this revision.
baloghadamsoftware added reviewers: NoQ, Szelethus.
baloghadamsoftware added a project: clang.
Herald added subscribers: ASDenysPetrov, martong, steakhal, Charusso, 
gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, 
xazax.hun, whisperity.

Insert and delete operations of `insert()`, `erase()` (plus `insert_after()` 
and `erase_after()` for `std::forward_list`-like containers were not modeled 
yet. This patch fixes this issue.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D77125

Files:
  clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
  clang/test/Analysis/Inputs/system-header-simulator-cxx.h
  clang/test/Analysis/diagnostics/explicit-suppression.cpp
  clang/test/Analysis/iterator-modeling.cpp

Index: clang/test/Analysis/iterator-modeling.cpp
===================================================================
--- clang/test/Analysis/iterator-modeling.cpp
+++ clang/test/Analysis/iterator-modeling.cpp
@@ -868,8 +868,8 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
 
   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_iterator_position(i1)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.begin()}}
 }
 
 void list_insert_behind_begin(std::list<int> &L, int n) {
@@ -884,10 +884,10 @@
   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_iterator_position(i0)); // 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(i1)); // expected-warning{{$L.begin() + 1}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin()
   clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$L.begin()}}
 }
 
 template <typename Iter> Iter return_any_iterator(const Iter &It);
@@ -907,8 +907,8 @@
 
   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_iterator_position(i2)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1}}
 }
 
 void list_insert_ahead_of_end(std::list<int> &L, int n) {
@@ -926,7 +926,7 @@
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
   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
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$L.end() - 1}}
 }
 
 void list_insert_end(std::list<int> &L, int n) {
@@ -942,9 +942,9 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
-  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(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() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$L.end()}}
 }
 
 /// std::vector-like containers: Only the iterators before the insertion point
@@ -962,7 +962,7 @@
   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_iterator_position(i2)); FIXME: expect warning $V.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$V.begin()}}
 }
 
 void vector_insert_behind_begin(std::vector<int> &V, int n) {
@@ -977,8 +977,8 @@
   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_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_iterator_position(i0)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); //expected-warning{{$V.begin()}}
 }
 
 void vector_insert_unknown(std::vector<int> &V, int n) {
@@ -995,7 +995,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
 
   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_iterator_position(i3)); // expected-warning{{$i1}}
 }
 
 void vector_insert_ahead_of_end(std::vector<int> &V, int n) {
@@ -1011,7 +1011,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.end() - 1}}
 }
 
 void vector_insert_end(std::vector<int> &V, int n) {
@@ -1027,8 +1027,8 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
-  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
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.end()}}
 }
 
 /// std::deque-like containers: All iterators, including the past-the-end
@@ -1045,7 +1045,7 @@
   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_iterator_position(i2)); FIXME: expect warning $D.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$D.begin()}}
 }
 
 void deque_insert_behind_begin(std::deque<int> &D, int n) {
@@ -1060,7 +1060,7 @@
   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_iterator_position(i3)); FIXME: expect warning $D.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$D.begin() + 1}}
 }
 
 void deque_insert_unknown(std::deque<int> &D, int n) {
@@ -1076,7 +1076,7 @@
   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_iterator_position(i3)); FIXME: expect warning $i1 - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1}}
 }
 
 void deque_insert_ahead_of_end(std::deque<int> &D, int n) {
@@ -1091,7 +1091,7 @@
   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_iterator_position(i3)); FIXME: expect warning $D.end() - 2
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$D.end() - 1}}
 }
 
 void deque_insert_end(std::deque<int> &D, int n) {
@@ -1106,7 +1106,7 @@
   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_iterator_position(i3)); FIXME: expect warning $D.end() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$D.end()}}
 }
 
 /// insert_after()   [std::forward_list-like containers]
@@ -1131,8 +1131,8 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
 
   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_iterator_position(i1)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.begin() + 1}}
 }
 
 void forward_list_insert_after_behind_begin(std::forward_list<int> &FL, int n) {
@@ -1149,8 +1149,8 @@
 
   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_iterator_position(i2)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$FL.begin() + 2}}
 }
 
 void forward_list_insert_after_unknown(std::forward_list<int> &FL, int n) {
@@ -1168,8 +1168,8 @@
 
   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_iterator_position(i2)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 1}}
 }
 
 /// emplace()
@@ -1196,8 +1196,8 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
 
   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_iterator_position(i1)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.begin()}}
 }
 
 void list_emplace_behind_begin(std::list<int> &L, int n) {
@@ -1212,10 +1212,10 @@
   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_iterator_position(i0)); // 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(i1)); // expected-warning{{$L.begin() + 1}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin()
   clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$L.begin() + 1}}
 }
 
 template <typename Iter> Iter return_any_iterator(const Iter &It);
@@ -1235,8 +1235,8 @@
 
   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_iterator_position(i2)); // expected-warning{{$L.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i}}
 }
 
 void list_emplace_ahead_of_end(std::list<int> &L, int n) {
@@ -1254,7 +1254,7 @@
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
   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
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$L.end() - 1}}
 }
 
 void list_emplace_end(std::list<int> &L, int n) {
@@ -1270,9 +1270,9 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
-  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(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() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$L.end()}}
 }
 
 /// std::vector-like containers: Only the iterators before the emplacement point
@@ -1289,7 +1289,7 @@
 
   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_iterator_position(i2)); FIXME: expect warning $V.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$V.begin()}}
 }
 
 void vector_emplace_behind_begin(std::vector<int> &V, int n) {
@@ -1304,8 +1304,8 @@
   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_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_iterator_position(i0)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // // expected-warning{{$V.begin() + 1}}
 }
 
 void vector_emplace_unknown(std::vector<int> &V, int n) {
@@ -1322,7 +1322,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
 
   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_iterator_position(i3)); // expected-warning{{$i1}}
 }
 
 void vector_emplace_ahead_of_end(std::vector<int> &V, int n) {
@@ -1338,7 +1338,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.end() - 1}}
 }
 
 void vector_emplace_end(std::vector<int> &V, int n) {
@@ -1354,8 +1354,8 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
-  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
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning{{$V.end() - 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.end()}}
 }
 
 /// std::deque-like containers: All iterators, including the past-the-end
@@ -1371,7 +1371,7 @@
 
   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_iterator_position(i2)); FIXME: expect warning $D.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$D.begin()}}
 }
 
 void deque_emplace_behind_begin(std::deque<int> &D, int n) {
@@ -1385,7 +1385,7 @@
   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_iterator_position(i3)); FIXME: expect warning $D.begin() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$D.begin() + 1}}
 }
 
 void deque_emplace_unknown(std::deque<int> &D, int n) {
@@ -1401,7 +1401,7 @@
   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_iterator_position(i3)); FIXME: expect warning $i1 - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1}}
 }
 
 void deque_emplace_ahead_of_end(std::deque<int> &D, int n) {
@@ -1416,7 +1416,7 @@
   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_iterator_position(i3)); FIXME: expect warning $D.end() - 2
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$D.end() - 1}}
 }
 
 void deque_emplace_end(std::deque<int> &D, int n) {
@@ -1431,7 +1431,7 @@
   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_iterator_position(i3)); FIXME: expect warning $D.end() - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$D.end()}}
 }
 
 /// emplace_after()   [std::forward_list-like containers]
@@ -1456,8 +1456,8 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i1)); //expected-warning{{TRUE}}
 
   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_iterator_position(i1)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$FL.begin() + 1}}
 }
 
 void forward_list_emplace_after_behind_begin(std::forward_list<int> &FL,
@@ -1475,8 +1475,8 @@
 
   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_iterator_position(i2)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$FL.begin() + 2}}
 }
 
 void forward_list_emplace_after_unknown(std::forward_list<int> &FL, int n) {
@@ -1494,8 +1494,8 @@
 
   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_iterator_position(i2)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 1}}
 }
 
 /// erase()
@@ -1524,7 +1524,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
 
   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_iterator_position(i3)); // expected-warning{{$L.begin() + 1}}
   clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
 }
 
@@ -1541,7 +1541,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
 
   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_iterator_position(i3)); // expected-warning{{$L.begin() + 2}}
   clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
 }
 
@@ -1559,7 +1559,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{TRUE}}
 
   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_iterator_position(i3)); // expected-warning{{$i1 + 1}}
   clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
 }
 
@@ -1577,7 +1577,7 @@
 
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
   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()
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$L.end()}}
 }
 
 /// std::vector-like containers: Invalidates iterators at or after the point of
@@ -1595,7 +1595,7 @@
   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_iterator_position(i3)); FIXME: expect warning $V.begin() + 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.begin() + 1}}
 }
 
 void vector_erase_behind_begin(std::vector<int> &V, int n) {
@@ -1611,7 +1611,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
 
   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_iterator_position(i3)); // expected-warning{{$V.begin() + 2}}
 }
 
 void vector_erase_unknown(std::vector<int> &V) {
@@ -1628,7 +1628,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
 
   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_iterator_position(i3)); // expected-warning{{$i1 + 1}}
 }
 
 void vector_erase_ahead_of_end(std::vector<int> &V) {
@@ -1644,7 +1644,7 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i2)); //expected-warning{{FALSE}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end()
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.end()}}
 }
 
 /// std::deque-like containers: All iterators are invalidated, unless the erased
@@ -1667,7 +1667,7 @@
   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_iterator_position(i3)); FIXME: expect warning $D.begin() + 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$D.begin() + 1}}
 }
 
 void deque_erase_behind_begin(std::deque<int> &D, int n) {
@@ -1682,7 +1682,7 @@
   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_iterator_position(i3)); FIXME: expect warning $D.begin() + 2
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$D.begin() + 2}}
 }
 
 void deque_erase_unknown(std::deque<int> &D) {
@@ -1698,7 +1698,7 @@
   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_iterator_position(i3)); FIXME: expect warning $i1 + 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 1}}
 }
 
 void deque_erase_ahead_of_end(std::deque<int> &D) {
@@ -1713,7 +1713,7 @@
   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_iterator_position(i3)); FIXME: expect warning $D.end()
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$D.end()}}
 }
 
 /// erase_after()   [std::forward_list-like containers]
@@ -1744,9 +1744,9 @@
   clang_analyzer_eval(clang_analyzer_iterator_validity(i3)); //expected-warning{{TRUE}}
 
   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_iterator_position(i2)); // expected-warning{{$FL.begin() + 2}}
   clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i4)); // expected-warning{{$FL.begin() + 2}}
 }
 
 void forward_list_erase_after_unknown(std::forward_list<int> &FL) {
@@ -1770,9 +1770,9 @@
 
   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_iterator_position(i3)); // expected-warning{{$i1 + 2}}
   clang_analyzer_express(clang_analyzer_iterator_position(i4)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i5)); // expected-warning{{$i1 + 2}}
 }
 
 struct simple_iterator_base {
Index: clang/test/Analysis/diagnostics/explicit-suppression.cpp
===================================================================
--- clang/test/Analysis/diagnostics/explicit-suppression.cpp
+++ clang/test/Analysis/diagnostics/explicit-suppression.cpp
@@ -19,6 +19,6 @@
 void testCopyNull(C *I, C *E) {
   std::copy(I, E, (C *)0);
 #ifndef SUPPRESSED
-  // expected-warning@../Inputs/system-header-simulator-cxx.h:698 {{Called C++ object pointer is null}}
+  // expected-warning@../Inputs/system-header-simulator-cxx.h:704 {{Called C++ object pointer is null}}
 #endif
 }
Index: clang/test/Analysis/Inputs/system-header-simulator-cxx.h
===================================================================
--- clang/test/Analysis/Inputs/system-header-simulator-cxx.h
+++ clang/test/Analysis/Inputs/system-header-simulator-cxx.h
@@ -88,6 +88,9 @@
 
   const Ptr& base() const { return ptr; }
 
+  template <typename UT, typename UPtr, typename URef>
+  friend struct __vector_iterator;
+
 private:
   Ptr ptr;
 };
@@ -143,6 +146,9 @@
 
   const Ptr& base() const { return ptr; }
 
+  template <typename UT, typename UPtr, typename URef>
+  friend struct __deque_iterator;
+
 private:
   Ptr ptr;
 };
@@ -175,11 +181,11 @@
   Ref 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; }
+  bool operator==(const iterator &rhs) const { return item == rhs.item; }
+  bool operator==(const const_iterator &rhs) const { return item == rhs.item; }
 
-  bool operator!=(const iterator &rhs) const { return item != rhs->item; }
-  bool operator!=(const const_iterator &rhs) const { return item != rhs->item; }
+  bool operator!=(const iterator &rhs) const { return item != rhs.item; }
+  bool operator!=(const const_iterator &rhs) const { return item != rhs.item; }
 
   const T* &base() const { return item; }
 
@@ -211,11 +217,11 @@
   Ref 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; }
+  bool operator==(const iterator &rhs) const { return item == rhs.item; }
+  bool operator==(const const_iterator &rhs) const { return item == rhs.item; }
 
-  bool operator!=(const iterator &rhs) const { return item != rhs->item; }
-  bool operator!=(const const_iterator &rhs) const { return item != rhs->item; }
+  bool operator!=(const iterator &rhs) const { return item != rhs.item; }
+  bool operator!=(const const_iterator &rhs) const { return item != rhs.item; }
 
   const T* &base() const { return item; }
 
Index: clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
@@ -44,12 +44,18 @@
   void handlePopBack(CheckerContext &C, SVal Cont, const Expr *ContE) const;
   void handlePushFront(CheckerContext &C, SVal Cont, const Expr *ContE) const;
   void handlePopFront(CheckerContext &C, SVal Cont, const Expr *ContE) const;
-  void handleInsert(CheckerContext &C, SVal Cont, SVal Iter) const;
-  void handleErase(CheckerContext &C, SVal Cont, SVal Iter) const;
-  void handleErase(CheckerContext &C, SVal Cont, SVal Iter1, SVal Iter2) const;
-  void handleEraseAfter(CheckerContext &C, SVal Cont, SVal Iter) const;
+  void handleInsert(CheckerContext &C, SVal Cont, SVal Iter,
+                    SVal RetVal) const;
+  void handleInsertAfter(CheckerContext &C, SVal Cont, SVal Iter,
+                         SVal RetVal) const;
+  void handleErase(CheckerContext &C, SVal Cont, SVal Iter,
+                    SVal RetVal) const;
+  void handleErase(CheckerContext &C, SVal Cont, SVal Iter1, SVal Iter2,
+                    SVal RetVal) const;
+  void handleEraseAfter(CheckerContext &C, SVal Cont, SVal Iter,
+                        SVal RetVal) const;
   void handleEraseAfter(CheckerContext &C, SVal Cont, SVal Iter1,
-                        SVal Iter2) const;
+                        SVal Iter2, SVal RetVal) const;
   const NoteTag *getChangeTag(CheckerContext &C, StringRef Text,
                               const MemRegion *ContReg,
                               const Expr *ContE) const;
@@ -66,9 +72,9 @@
   using NoItParamFn = void (ContainerModeling::*)(CheckerContext &, SVal,
                                                   const Expr *) const;
   using OneItParamFn = void (ContainerModeling::*)(CheckerContext &, SVal,
-                                                   SVal) const;
+                                                   SVal, SVal) const;
   using TwoItParamFn = void (ContainerModeling::*)(CheckerContext &, SVal, SVal,
-                                                   SVal) const;
+                                                   SVal, SVal) const;
 
   CallDescriptionMap<NoItParamFn> NoIterParamFunctions = {
     {{0, "clear", 0},
@@ -92,8 +98,12 @@
   CallDescriptionMap<OneItParamFn> OneIterParamFunctions = {
     {{0, "insert", 2},
      &ContainerModeling::handleInsert},
+    {{0, "insert_after", 2},
+     &ContainerModeling::handleInsertAfter},
     {{0, "emplace", 2},
      &ContainerModeling::handleInsert},
+    {{0, "emplace_after", 2},
+     &ContainerModeling::handleInsertAfter},
     {{0, "erase", 1},
      &ContainerModeling::handleErase},
     {{0, "erase_after", 1},
@@ -188,14 +198,15 @@
 
       const OneItParamFn *Handler1 = OneIterParamFunctions.lookup(Call);
       if (Handler1) {
-        (this->**Handler1)(C, InstCall->getCXXThisVal(), Call.getArgSVal(0));
+        (this->**Handler1)(C, InstCall->getCXXThisVal(), Call.getArgSVal(0),
+                           Call.getReturnValue());
         return;
       }
 
       const TwoItParamFn *Handler2 = TwoIterParamFunctions.lookup(Call);
       if (Handler2) {
         (this->**Handler2)(C, InstCall->getCXXThisVal(), Call.getArgSVal(0),
-                           Call.getArgSVal(1));
+                           Call.getArgSVal(1), Call.getReturnValue());
         return;
       }
 
@@ -445,12 +456,10 @@
       State = invalidateIteratorPositions(State, EndSym, BO_GE);
     }
     auto &SymMgr = C.getSymbolManager();
-    auto &BVF = SymMgr.getBasicVals();
     auto &SVB = C.getSValBuilder();
     const auto newEndSym =
-      SVB.evalBinOp(State, BO_Add,
-                    nonloc::SymbolVal(EndSym),
-                    nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))),
+      SVB.evalBinOp(State, BO_Add, nonloc::SymbolVal(EndSym),
+                    SVB.makeIntVal(1, false),
                     SymMgr.getType(EndSym)).getAsSymbol();
     const NoteTag *ChangeTag =
       getChangeTag(C, "extended to the back by 1 position", ContReg, ContE);
@@ -474,12 +483,10 @@
 
   if (const auto EndSym = CData->getEnd()) {
     auto &SymMgr = C.getSymbolManager();
-    auto &BVF = SymMgr.getBasicVals();
     auto &SVB = C.getSValBuilder();
     const auto BackSym =
-      SVB.evalBinOp(State, BO_Sub,
-                    nonloc::SymbolVal(EndSym),
-                    nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))),
+      SVB.evalBinOp(State, BO_Sub, nonloc::SymbolVal(EndSym),
+                    SVB.makeIntVal(1, false),
                     SymMgr.getType(EndSym)).getAsSymbol();
     const NoteTag *ChangeTag =
       getChangeTag(C, "shrank from the back by 1 position", ContReg, ContE);
@@ -519,12 +526,10 @@
 
     if (const auto BeginSym = CData->getBegin()) {
       auto &SymMgr = C.getSymbolManager();
-      auto &BVF = SymMgr.getBasicVals();
       auto &SVB = C.getSValBuilder();
       const auto newBeginSym =
-        SVB.evalBinOp(State, BO_Sub,
-                      nonloc::SymbolVal(BeginSym),
-                      nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))),
+        SVB.evalBinOp(State, BO_Sub, nonloc::SymbolVal(BeginSym),
+                      SVB.makeIntVal(1, false),
                       SymMgr.getType(BeginSym)).getAsSymbol();
       const NoteTag *ChangeTag =
         getChangeTag(C, "extended to the front by 1 position", ContReg, ContE);
@@ -556,12 +561,10 @@
       State = invalidateIteratorPositions(State, BeginSym, BO_EQ);
     }
     auto &SymMgr = C.getSymbolManager();
-    auto &BVF = SymMgr.getBasicVals();
     auto &SVB = C.getSValBuilder();
     const auto newBeginSym =
-      SVB.evalBinOp(State, BO_Add,
-                    nonloc::SymbolVal(BeginSym),
-                    nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))),
+      SVB.evalBinOp(State, BO_Add, nonloc::SymbolVal(BeginSym),
+                    SVB.makeIntVal(1, false),
                     SymMgr.getType(BeginSym)).getAsSymbol();
     const NoteTag *ChangeTag =
       getChangeTag(C, "shrank from the front by 1 position", ContReg, ContE);
@@ -571,7 +574,7 @@
 }
 
 void ContainerModeling::handleInsert(CheckerContext &C, SVal Cont,
-                                     SVal Iter) const {
+                                     SVal Iter, SVal RetVal) const {
   const auto *ContReg = Cont.getAsRegion();
   if (!ContReg)
     return;
@@ -597,12 +600,44 @@
         State = setContainerData(State, ContReg, CData->newEnd(nullptr));
       }
     }
-    C.addTransition(State);
   }
+
+  // Set the return value
+  auto RetPos =
+    IteratorPosition::getPosition(Pos->getContainer(), Pos->getOffset());
+  State = setIteratorPosition(State, RetVal, RetPos);
+
+  C.addTransition(State);
+}
+
+void ContainerModeling::handleInsertAfter(CheckerContext &C, SVal Cont,
+                                     SVal Iter, SVal RetVal) const {
+  const auto *ContReg = Cont.getAsRegion();
+  if (!ContReg)
+    return;
+
+  ContReg = ContReg->getMostDerivedObjectRegion();
+
+  auto State = C.getState();
+  const auto *Pos = getIteratorPosition(State, Iter);
+  if (!Pos)
+    return;
+
+  // Set the return value
+  auto &SymMgr = C.getSymbolManager();
+  auto &SVB = C.getSValBuilder();
+  const auto RetOffset =
+    SVB.evalBinOp(State, BO_Add, nonloc::SymbolVal(Pos->getOffset()),
+                  SVB.makeIntVal(1, false),
+                  SymMgr.getType(Pos->getOffset())).getAsSymbol();
+  auto RetPos = IteratorPosition::getPosition(Pos->getContainer(), RetOffset);
+  State = setIteratorPosition(State, RetVal, RetPos);
+
+  C.addTransition(State);
 }
 
 void ContainerModeling::handleErase(CheckerContext &C, SVal Cont,
-                                    SVal Iter) const {
+                                    SVal Iter, SVal RetVal) const {
   const auto *ContReg = Cont.getAsRegion();
   if (!ContReg)
     return;
@@ -632,11 +667,22 @@
   } else {
     State = invalidateIteratorPositions(State, Pos->getOffset(), BO_EQ);
   }
+
+  // Set the return value
+  auto &SymMgr = C.getSymbolManager();
+  auto &SVB = C.getSValBuilder();
+  const auto RetOffset =
+    SVB.evalBinOp(State, BO_Add, nonloc::SymbolVal(Pos->getOffset()),
+                  SVB.makeIntVal(1, false),
+                  SymMgr.getType(Pos->getOffset())).getAsSymbol();
+  auto RetPos = IteratorPosition::getPosition(Pos->getContainer(), RetOffset);
+  State = setIteratorPosition(State, RetVal, RetPos);
+
   C.addTransition(State);
 }
 
 void ContainerModeling::handleErase(CheckerContext &C, SVal Cont, SVal Iter1,
-                                    SVal Iter2) const {
+                                    SVal Iter2, SVal RetVal) const {
   const auto *ContReg = Cont.getAsRegion();
   if (!ContReg)
     return;
@@ -668,11 +714,17 @@
     State = invalidateIteratorPositions(State, Pos1->getOffset(), BO_GE,
                                         Pos2->getOffset(), BO_LT);
   }
+
+  // Set the return value
+  auto RetPos =
+      IteratorPosition::getPosition(Pos2->getContainer(), Pos2->getOffset());
+  State = setIteratorPosition(State, RetVal, RetPos);
+
   C.addTransition(State);
 }
 
 void ContainerModeling::handleEraseAfter(CheckerContext &C, SVal Cont,
-                                        SVal Iter) const {
+                                         SVal Iter, SVal RetVal) const {
   auto State = C.getState();
   const auto *Pos = getIteratorPosition(State, Iter);
   if (!Pos)
@@ -681,19 +733,27 @@
   // Invalidate the deleted iterator position, which is the position of the
   // parameter plus one.
   auto &SymMgr = C.getSymbolManager();
-  auto &BVF = SymMgr.getBasicVals();
   auto &SVB = C.getSValBuilder();
   const auto NextSym =
-    SVB.evalBinOp(State, BO_Add,
-                  nonloc::SymbolVal(Pos->getOffset()),
-                  nonloc::ConcreteInt(BVF.getValue(llvm::APSInt::get(1))),
+    SVB.evalBinOp(State, BO_Add, nonloc::SymbolVal(Pos->getOffset()),
+                  SVB.makeIntVal(1, false),
                   SymMgr.getType(Pos->getOffset())).getAsSymbol();
   State = invalidateIteratorPositions(State, NextSym, BO_EQ);
+
+  // Set the return value
+  const auto RetOffset =
+    SVB.evalBinOp(State, BO_Add, nonloc::SymbolVal(NextSym),
+                  SVB.makeIntVal(1, false),
+                  SymMgr.getType(NextSym)).getAsSymbol();
+  auto RetPos = IteratorPosition::getPosition(Pos->getContainer(), RetOffset);
+  State = setIteratorPosition(State, RetVal, RetPos);
+
   C.addTransition(State);
 }
 
 void ContainerModeling::handleEraseAfter(CheckerContext &C, SVal Cont,
-                                         SVal Iter1, SVal Iter2) const {
+                                         SVal Iter1, SVal Iter2,
+                                         SVal RetVal) const {
   auto State = C.getState();
   const auto *Pos1 = getIteratorPosition(State, Iter1);
   const auto *Pos2 = getIteratorPosition(State, Iter2);
@@ -703,6 +763,12 @@
   // Invalidate the deleted iterator position range (first..last)
   State = invalidateIteratorPositions(State, Pos1->getOffset(), BO_GT,
                                       Pos2->getOffset(), BO_LT);
+
+  // Set the return value
+  auto RetPos =
+      IteratorPosition::getPosition(Pos2->getContainer(), Pos2->getOffset());
+  State = setIteratorPosition(State, RetVal, RetPos);
+
   C.addTransition(State);
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to