baloghadamsoftware updated this revision to Diff 278395.
baloghadamsoftware added a comment.

Protection agains `Unknown` return values added.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D77125/new/

https://reviews.llvm.org/D77125

Files:
  clang/lib/StaticAnalyzer/Checkers/ContainerModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/Iterator.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
@@ -873,9 +873,9 @@
   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_iterator_position(i0)); // expected-warning-re {{$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-re {{$L.end(){{$}}}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+  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) {
@@ -890,10 +890,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-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() - 1
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$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-re {{$L.end(){{$}}}}
+  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(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);
@@ -911,10 +911,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-re {{$L.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
+  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(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) {
@@ -929,10 +929,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-re {{$L.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2
+  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)); // expected-warning{{$L.end() - 1}}
 }
 
 void list_insert_end(std::list<int> &L, int n) {
@@ -947,10 +947,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-re {{$L.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} FIXME: should be $L.end() - 2
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1
+  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)); // expected-warning{{$L.end()}}
 }
 
 /// std::vector-like containers: Only the iterators before the insertion point
@@ -968,7 +968,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) {
@@ -983,8 +983,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-re {{$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) {
@@ -1000,8 +1000,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-re {{$V.begin(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1}}
 }
 
 void vector_insert_ahead_of_end(std::vector<int> &V, int n) {
@@ -1016,8 +1016,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-re {{$V.begin(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.end() - 1}}
 }
 
 void vector_insert_end(std::vector<int> &V, int n) {
@@ -1032,9 +1032,9 @@
   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_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$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(i0)); // expected-warning{{$V.begin()}}
+  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
@@ -1051,7 +1051,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) {
@@ -1066,7 +1066,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) {
@@ -1082,7 +1082,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) {
@@ -1097,7 +1097,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) {
@@ -1112,7 +1112,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]
@@ -1136,9 +1136,9 @@
   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_iterator_position(i0)); // expected-warning-re {{$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-re {{$FL.end(){{$}}}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+  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) {
@@ -1153,10 +1153,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-re {{$FL.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$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-re {{$FL.end(){{$}}}}
+  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(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) {
@@ -1172,10 +1172,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-re {{$FL.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}}
+  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(i2)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 1}}
 }
 
 /// emplace()
@@ -1201,9 +1201,9 @@
   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_iterator_position(i0)); // expected-warning-re {{$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-re {{$L.end(){{$}}}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+  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) {
@@ -1218,10 +1218,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-re {{$L.begin(){{$}}}} FIXME: Should be $L.begin() - 1
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$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-re {{$L.end(){{$}}}}
+  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(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);
@@ -1239,10 +1239,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-re {{$L.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i - 1
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
+  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(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) {
@@ -1257,10 +1257,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-re {{$L.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 2
+  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)); // expected-warning{{$L.end() - 1}}
 }
 
 void list_emplace_end(std::list<int> &L, int n) {
@@ -1275,10 +1275,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-re {{$L.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$L.end() - 1{{$}}}} FIXME: should be $L.end() - 2
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end() - 1
+  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)); // expected-warning{{$L.end()}}
 }
 
 /// std::vector-like containers: Only the iterators before the emplacement point
@@ -1295,7 +1295,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) {
@@ -1310,8 +1310,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-re {{$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) {
@@ -1327,8 +1327,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-re {{$V.begin(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expecte warning $i1 - 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1}}
 }
 
 void vector_emplace_ahead_of_end(std::vector<int> &V, int n) {
@@ -1343,8 +1343,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-re {{$V.begin(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end() - 2
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.end() - 1}}
 }
 
 void vector_emplace_end(std::vector<int> &V, int n) {
@@ -1359,9 +1359,9 @@
   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_iterator_position(i0)); // expected-warning-re {{$V.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$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(i0)); // expected-warning{{$V.begin()}}
+  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
@@ -1377,7 +1377,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) {
@@ -1391,7 +1391,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) {
@@ -1407,7 +1407,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) {
@@ -1422,7 +1422,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) {
@@ -1437,7 +1437,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]
@@ -1461,9 +1461,9 @@
   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_iterator_position(i0)); // expected-warning-re {{$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-re {{$FL.end(){{$}}}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$FL.begin()}}
+  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,
@@ -1479,10 +1479,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-re {{$FL.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$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-re {{$FL.end(){{$}}}}
+  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(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) {
@@ -1498,10 +1498,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-re {{$FL.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$FL.end(){{$}}}}
+  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(i2)); // expected-warning{{$FL.end()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 1}}
 }
 
 /// erase()
@@ -1529,9 +1529,9 @@
   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(i1)); // expected-warning-re {{$L.begin() + 1{{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.begin() + 1
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-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()}}
 }
 
 void list_erase_behind_begin(std::list<int> &L, int n) {
@@ -1546,9 +1546,9 @@
   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_iterator_position(i0)); // expected-warning-re {{$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(i2)); // expected-warning-re {{$L.end(){{$}}}}
+  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)); // expected-warning{{$L.begin() + 2}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
 }
 
 void list_erase_unknown(std::list<int> &L) {
@@ -1564,9 +1564,9 @@
   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_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$L.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 1}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning{{$L.end()}}
 }
 
 void list_erase_ahead_of_end(std::list<int> &L) {
@@ -1581,9 +1581,9 @@
   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_iterator_position(i0)); // expected-warning-re {{$L.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$L.end(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $L.end()
+  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)); // expected-warning{{$L.end()}}
 }
 
 /// std::vector-like containers: Invalidates iterators at or after the point of
@@ -1601,7 +1601,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) {
@@ -1616,8 +1616,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-re {{$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(i0)); // expected-warning{{$V.begin()}} FIXME: Should be $V.begin() + 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.begin() + 2}}
 }
 
 void vector_erase_unknown(std::vector<int> &V) {
@@ -1633,8 +1633,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-re {{$V.begin(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $i1 + 1
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$i1 + 1}}
 }
 
 void vector_erase_ahead_of_end(std::vector<int> &V) {
@@ -1649,8 +1649,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-re {{$V.begin(){{$}}}}
-  // clang_analyzer_express(clang_analyzer_iterator_position(i3)); FIXME: expect warning $V.end()
+  clang_analyzer_express(clang_analyzer_iterator_position(i0)); // expected-warning{{$V.begin()}}
+  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning{{$V.end()}}
 }
 
 /// std::deque-like containers: All iterators are invalidated, unless the erased
@@ -1673,7 +1673,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) {
@@ -1688,7 +1688,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) {
@@ -1704,7 +1704,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) {
@@ -1719,7 +1719,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]
@@ -1749,10 +1749,10 @@
   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_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i2)); // expected-warning-re {{$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(i3)); // expected-warning-re {{$FL.end(){{$}}}}
+  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}}
+  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) {
@@ -1774,11 +1774,11 @@
   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_iterator_position(i0)); // expected-warning-re {{$FL.begin(){{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$i1{{$}}}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i3)); // expected-warning-re {{$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(i4)); // expected-warning-re {{$FL.end(){{$}}}}
+  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}}
+  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:699 {{Called C++ object pointer is null}}
+  // expected-warning@../Inputs/system-header-simulator-cxx.h:705 {{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/Iterator.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/Iterator.cpp
+++ clang/lib/StaticAnalyzer/Checkers/Iterator.cpp
@@ -17,7 +17,7 @@
 namespace iterator {
 
 bool isIteratorType(const QualType &Type) {
-  if (Type->isPointerType())
+  if (Type->getUnqualifiedDesugaredType()->isPointerType())
     return true;
 
   const auto *CRD = Type->getUnqualifiedDesugaredType()->getAsCXXRecordDecl();
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},
@@ -179,6 +189,29 @@
     }
   } else {
     if (const auto *InstCall = dyn_cast<CXXInstanceCall>(&Call)) {
+      const auto *OrigExpr = Call.getOriginExpr();
+      if (!OrigExpr)
+        return;
+
+      QualType RetType = Call.getResultType();
+      SVal RetVal = Call.getReturnValue();
+      if (isIteratorType(RetType) && RetVal.isUnknown()) {
+        ProgramStateRef State = C.getState();
+        auto &SymMgr = C.getSymbolManager();
+        auto *LCtx = C.getLocationContext();
+        SymbolRef RetSym = SymMgr.conjureSymbol(OrigExpr, LCtx, RetType,
+                                                C.blockCount());
+        if (RetType->getUnqualifiedDesugaredType()->isPointerType()) {
+          auto &RegMgr = C.getStoreManager().getRegionManager();
+          const MemRegion *RetReg = RegMgr.getSymbolicRegion(RetSym);
+          RetVal = loc::MemRegionVal(RetReg);
+        } else {
+          RetVal = nonloc::SymbolVal(RetSym);
+        }
+        State = State->BindExpr(OrigExpr, LCtx, RetVal);
+        C.addTransition(State);
+      }
+
       const NoItParamFn *Handler0 = NoIterParamFunctions.lookup(Call);
       if (Handler0) {
         (this->**Handler0)(C, InstCall->getCXXThisVal(),
@@ -188,30 +221,25 @@
 
       const OneItParamFn *Handler1 = OneIterParamFunctions.lookup(Call);
       if (Handler1) {
-        (this->**Handler1)(C, InstCall->getCXXThisVal(), Call.getArgSVal(0));
+        (this->**Handler1)(C, InstCall->getCXXThisVal(), Call.getArgSVal(0),
+                           RetVal);
         return;
       }
 
       const TwoItParamFn *Handler2 = TwoIterParamFunctions.lookup(Call);
       if (Handler2) {
         (this->**Handler2)(C, InstCall->getCXXThisVal(), Call.getArgSVal(0),
-                           Call.getArgSVal(1));
+                           Call.getArgSVal(1), RetVal);
         return;
       }
 
-      const auto *OrigExpr = Call.getOriginExpr();
-      if (!OrigExpr)
-        return;
-
       if (isBeginCall(Func)) {
-        handleBegin(C, OrigExpr, Call.getReturnValue(),
-                    InstCall->getCXXThisVal());
+        handleBegin(C, OrigExpr, RetVal, InstCall->getCXXThisVal());
         return;
       }
 
       if (isEndCall(Func)) {
-        handleEnd(C, OrigExpr, Call.getReturnValue(),
-                  InstCall->getCXXThisVal());
+        handleEnd(C, OrigExpr, RetVal, InstCall->getCXXThisVal());
         return;
       }
     }
@@ -445,12 +473,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 +500,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 +543,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 +578,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 +591,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 +617,46 @@
         State = setContainerData(State, ContReg, CData->newEnd(nullptr));
       }
     }
-    C.addTransition(State);
   }
+
+  // Set the return value
+  if (!RetVal.isUnknown()) {
+    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
+  if (!RetVal.isUnknown()) {
+    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 +686,23 @@
   } else {
     State = invalidateIteratorPositions(State, Pos->getOffset(), BO_EQ);
   }
+
+  // Set the return value
+  if (!RetVal.isUnknown()) {
+    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 +734,18 @@
     State = invalidateIteratorPositions(State, Pos1->getOffset(), BO_GE,
                                         Pos2->getOffset(), BO_LT);
   }
+
+  // Set the return value
+  if (!RetVal.isUnknown()) {
+    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 +754,28 @@
   // 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
+  if (!RetVal.isUnknown()) {
+    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 +785,13 @@
   // Invalidate the deleted iterator position range (first..last)
   State = invalidateIteratorPositions(State, Pos1->getOffset(), BO_GT,
                                       Pos2->getOffset(), BO_LT);
+
+  // Set the return value
+  if (!RetVal.isUnknown()) {
+    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