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

Rebased, no tricks with `LazyCompoundVal`s are used anymore.


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

https://reviews.llvm.org/D75677

Files:
  clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
  clang/test/Analysis/iterator-modeling.cpp
  clang/test/Analysis/iterator-range.cpp

Index: clang/test/Analysis/iterator-range.cpp
===================================================================
--- clang/test/Analysis/iterator-range.cpp
+++ clang/test/Analysis/iterator-range.cpp
@@ -957,3 +957,4 @@
   *i; // expected-warning{{Past-the-end iterator dereferenced}}
       // expected-note@-1{{Past-the-end iterator dereferenced}}
 }
+
Index: clang/test/Analysis/iterator-modeling.cpp
===================================================================
--- clang/test/Analysis/iterator-modeling.cpp
+++ clang/test/Analysis/iterator-modeling.cpp
@@ -116,7 +116,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
-  auto j = i++; // expected-note 2{{Iterator 'i' incremented by 1}}
+  auto j = i++; // expected-note{{Iterator 'i' incremented by 1}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.begin() + 1{{$}}}}
                                                                // expected-note@-1{{$v.begin() + 1}}
@@ -129,7 +129,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
 
-  auto j = i--; // expected-note 2{{Iterator 'i' decremented by 1}}
+  auto j = i--; // expected-note{{Iterator 'i' decremented by 1}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning-re {{$v.end() - 1{{$}}}}
                                                                // expected-note@-1{{$v.end() - 1}}
@@ -223,7 +223,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
-  auto i2 = i1 + 2; // expected-note 4{{Iterator 'i1' incremented by 2}}
+  auto i2 = i1 + 2; // expected-note 2{{Iterator 'i1' incremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -231,8 +231,6 @@
                                                                     // expected-note@-1{{$v.begin()}}
   clang_analyzer_express(clang_analyzer_iterator_position(i2));     // expected-warning-re{{$v.begin() + 2{{$}}}}
                                                                     // expected-note@-1{{$v.begin() + 2}}
-  clang_analyzer_express(clang_analyzer_iterator_position(i2));     // expected-warning{{$v.begin() + 2}}
-                                                                    // expected-note@-1{{$v.begin() + 2}}
 }
 
 void plus_negative(const std::vector<int> &v) {
@@ -240,7 +238,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
 
-  auto i2 = i1 + (-2); // expected-note 3{{Iterator 'i1' decremented by 2}}
+  auto i2 = i1 + (-2); // expected-note 2{{Iterator 'i1' decremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -255,7 +253,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
-  auto i2 = i1 + 0; // expected-note 2{{Iterator 'i1' unchanged}}
+  auto i2 = i1 + 0; // expected-note{{Iterator 'i1' unchanged}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -268,7 +266,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
 
-  auto i2 = i1 - 2;  // expected-note 3{{Iterator 'i1' decremented by 2}}
+  auto i2 = i1 - 2; // expected-note 2{{Iterator 'i1' decremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -283,7 +281,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
-  auto i2 = i1 - (-2); // expected-note 3{{Iterator 'i1' incremented by 2}}
+  auto i2 = i1 - (-2); // expected-note 2{{Iterator 'i1' incremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -298,7 +296,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
-  auto i2 = i1 - 0; // expected-note 2{{Iterator 'i1' unchanged}}
+  auto i2 = i1 - 0; // expected-note{{Iterator 'i1' unchanged}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -312,7 +310,7 @@
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
   auto i2 = i1;
-  ++i1;  // expected-note 2{{Iterator 'i1' incremented by 1}}
+  ++i1;  // expected-note{{Iterator 'i1' incremented by 1}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin() + 1{{$}}}}
                                                                 // expected-note@-1{{$v.begin() + 1}}
@@ -326,7 +324,7 @@
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
   auto i2 = i1;
-  ++i2;  // expected-note 2{{Iterator 'i2' incremented by 1}}
+  ++i2;  // expected-note{{Iterator 'i2' incremented by 1}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.begin(){{$}}}}
                                                                 // expected-note@-1{{$v.begin()}}
@@ -340,7 +338,7 @@
   clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
 
   auto i2 = i1;
-  --i1;  // expected-note 2{{Iterator 'i1' decremented by 1}}
+  --i1;  // expected-note{{Iterator 'i1' decremented by 1}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end() - 1{{$}}}}
                                                                 // expected-note@-1{{$v.end() - 1}}
@@ -354,7 +352,7 @@
   clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
 
   auto i2 = i1;
-  --i2;  // expected-note 2{{Iterator 'i2' decremented by 1}}
+  --i2;  // expected-note{{Iterator 'i2' decremented by 1}}
 
   clang_analyzer_express(clang_analyzer_iterator_position(i1)); // expected-warning-re {{$v.end(){{$}}}}
                                                                 // expected-note@-1{{$v.end()}}
@@ -535,7 +533,6 @@
 
 void list_move_assignment(std::list<int> &L1, std::list<int> &L2) {
   auto i0 = L1.cbegin(), i1 = L2.cbegin(), i2 = --L2.cend(), i3 = L2.cend();
-  // expected-note@-1 7{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L2), "$L2.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L2), "$L2.end()");
@@ -562,7 +559,6 @@
 
 void vector_move_assignment(std::vector<int> &V1, std::vector<int> &V2) {
   auto i0 = V1.cbegin(), i1 = V2.cbegin(), i2 = --V2.cend(), i3 = V2.cend();
-  // expected-note@-1 7{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V2), "$V2.begin()");
 
@@ -588,7 +584,6 @@
 
 void deque_move_assignment(std::deque<int> &D1, std::deque<int> &D2) {
   auto i0 = D1.cbegin(), i1 = D2.cbegin(), i2 = --D2.cend(), i3 = D2.cend();
-  // expected-note@-1 7{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D2), "$D2.begin()");
 
@@ -734,7 +729,7 @@
 
 void list_push_back(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
-  // expected-note@-1 6{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -760,7 +755,7 @@
 
 void vector_push_back(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
-  // expected-note@-1 5{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -785,7 +780,6 @@
 
 void deque_push_back(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -811,7 +805,7 @@
 
 void list_emplace_back(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
-  // expected-note@-1 6{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -837,7 +831,7 @@
 
 void vector_emplace_back(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
-  // expected-note@-1 5{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -862,7 +856,6 @@
 
 void deque_emplace_back(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -888,7 +881,6 @@
 
 void list_pop_back(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
-  // expected-note@-1 5{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -913,7 +905,6 @@
 
 void vector_pop_back(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
-  // expected-note@-1 4{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -937,7 +928,6 @@
 
 void deque_pop_back(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 4{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -988,7 +978,6 @@
 
 void deque_push_front(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -1057,7 +1046,6 @@
 
 void deque_emplace_front(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -1104,7 +1092,7 @@
 
 void list_pop_front(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
-  // expected-note@-1 5{{Iterator incremented by 1}}
+  // expected-note@-1{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -1129,7 +1117,7 @@
 
 void deque_pop_front(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
-  // expected-note@-1 5{{Iterator incremented by 1}}
+  // expected-note@-1{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -1154,7 +1142,7 @@
 
 void forward_list_pop_front(std::list<int> &FL, int n) {
   auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend();
-  // expected-note@-1 5{{Iterator incremented by 1}}
+  // expected-note@-1{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
@@ -1208,7 +1196,7 @@
 
 void list_insert_behind_begin(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
-  // expected-note@-1 6{{Iterator incremented by 1}}
+  // expected-note@-1{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -1260,7 +1248,7 @@
 
 void list_insert_ahead_of_end(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
-  // expected-note@-1 6{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -1285,7 +1273,7 @@
 
 void list_insert_end(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
-  // expected-note@-1 6{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -1330,7 +1318,6 @@
 
 void vector_insert_behind_begin(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
-  // expected-note@-1 4{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -1372,7 +1359,6 @@
 
 void vector_insert_ahead_of_end(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
-  // expected-note@-1 4{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -1393,7 +1379,7 @@
 
 void vector_insert_end(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
-  // expected-note@-1 5{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -1435,7 +1421,6 @@
 
 void deque_insert_behind_begin(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -1473,7 +1458,6 @@
 
 void deque_insert_ahead_of_end(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -1492,7 +1476,6 @@
 
 void deque_insert_end(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -1541,7 +1524,7 @@
 
 void forward_list_insert_after_behind_begin(std::forward_list<int> &FL, int n) {
   auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend();
-  // expected-note@-1 6{{Iterator incremented by 1}}
+  // expected-note@-1{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
@@ -1623,7 +1606,7 @@
 
 void list_emplace_behind_begin(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
-  // expected-note@-1 6{{Iterator incremented by 1}}
+  // expected-note@-1{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -1675,7 +1658,7 @@
 
 void list_emplace_ahead_of_end(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
-  // expected-note@-1 6{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -1700,7 +1683,7 @@
 
 void list_emplace_end(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
-  // expected-note@-1 6{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -1744,7 +1727,6 @@
 
 void vector_emplace_behind_begin(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
-  // expected-note@-1 4{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -1786,7 +1768,6 @@
 
 void vector_emplace_ahead_of_end(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
-  // expected-note@-1 4{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -1807,7 +1788,7 @@
 
 void vector_emplace_end(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
-  // expected-note@-1 5{{Iterator decremented by 1}}
+  // expected-note@-1{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -1848,7 +1829,6 @@
 
 void deque_emplace_behind_begin(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -1885,7 +1865,6 @@
 
 void deque_emplace_ahead_of_end(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -1904,7 +1883,6 @@
 
 void deque_emplace_end(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -1954,7 +1932,7 @@
 void forward_list_emplace_after_behind_begin(std::forward_list<int> &FL,
                                              int n) {
   auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = FL.cend();
-  // expected-note@-1 6{{Iterator incremented by 1}}
+  // expected-note@-1{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
@@ -2017,7 +1995,7 @@
 
 void list_erase_begin(std::list<int> &L) {
   auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
-  // expected-note@-1 5{{Iterator incremented by 1}}
+  // expected-note@-1{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -2040,7 +2018,6 @@
 
 void list_erase_behind_begin(std::list<int> &L, int n) {
   auto i0 = L.cbegin(), i1 = ++L.cbegin(), i2 = L.cend();
-  // expected-note@-1 5{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -2086,7 +2063,6 @@
 
 void list_erase_ahead_of_end(std::list<int> &L) {
   auto i0 = L.cbegin(), i1 = --L.cend(), i2 = L.cend();
-  // expected-note@-1 5{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(L), "$L.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(L), "$L.end()");
@@ -2112,7 +2088,6 @@
 
 void vector_erase_begin(std::vector<int> &V) {
   auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
-  // expected-note@-1 3{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -2131,7 +2106,6 @@
 
 void vector_erase_behind_begin(std::vector<int> &V, int n) {
   auto i0 = V.cbegin(), i1 = ++V.cbegin(), i2 = V.cend();
-  // expected-note@-1 4{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -2173,7 +2147,6 @@
 
 void vector_erase_ahead_of_end(std::vector<int> &V) {
   auto i0 = V.cbegin(), i1 = --V.cend(), i2 = V.cend();
-  // expected-note@-1 4{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(V), "$V.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(V), "$V.end()");
@@ -2202,7 +2175,6 @@
 
 void deque_erase_begin(std::deque<int> &D) {
   auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -2221,7 +2193,6 @@
 
 void deque_erase_behind_begin(std::deque<int> &D, int n) {
   auto i0 = D.cbegin(), i1 = ++D.cbegin(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -2259,7 +2230,6 @@
 
 void deque_erase_ahead_of_end(std::deque<int> &D) {
   auto i0 = D.cbegin(), i1 = --D.cend(), i2 = D.cend();
-  // expected-note@-1 3{{Iterator decremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(D), "$D.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(D), "$D.end()");
@@ -2291,9 +2261,9 @@
 
 void forward_list_erase_after_begin(std::forward_list<int> &FL) {
   auto i0 = FL.cbegin(), i1 = ++FL.cbegin(), i2 = i1, i3 = FL.cend();
-  // expected-note@-1 7{{Iterator incremented by 1}}
+  // expected-note@-1{{Iterator incremented by 1}}
   ++i2;
-  // expected-note@-1 7{{Iterator 'i2' incremented by 1}}
+  // expected-note@-1{{Iterator 'i2' incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
@@ -2322,11 +2292,10 @@
   auto i0 = FL.cbegin(), i1 = return_any_iterator(FL.cbegin()), i2 = i1,
     i3 = i1, i4 = FL.cend();
   ++i2;
-  // expected-note@-1 9{{Iterator 'i2' incremented by 1}}
   ++i3;
-  // expected-note@-1 9{{Iterator 'i3' incremented by 1}}
+  // expected-note@-1{{Iterator 'i3' incremented by 1}}
   ++i3;
-  // expected-note@-1 9{{Iterator 'i3' incremented by 1}}
+  // expected-note@-1{{Iterator 'i3' incremented by 1}}
 
   clang_analyzer_denote(clang_analyzer_container_begin(FL), "$FL.begin()");
   clang_analyzer_denote(clang_analyzer_container_end(FL), "$FL.end()");
@@ -2555,7 +2524,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(c), "$c.begin()");
 
-  auto i2 = i1 + 2; // expected-note 3{{Iterator 'i1' incremented by 2}}
+  auto i2 = i1 + 2; // expected-note 2{{Iterator 'i1' incremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &c); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -2570,7 +2539,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_end(c), "$c.end()");
 
-  auto i2 = i1 - 2; // expected-note 3{{Iterator 'i1' decremented by 2}}
+  auto i2 = i1 - 2; // expected-note 2{{Iterator 'i1' decremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &c); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -2598,8 +2567,8 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
-  auto k = ++j; // expected-note 2{{Iterator 'j' incremented by 1}}
-                // FIXME: Expect only one note.
+  auto k = ++j; // expected-note{{Iterator 'j' incremented by 1}}
+                // Only once!
 
   clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$v.begin()}}
                                                                // expected-note@-1{{$v.begin()}}
@@ -2613,8 +2582,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
-  auto k = ++j; // expected-note{{Iterator 'j' incremented by 1}}
-                // FIXME: expect no note.
+  auto k = ++j; // no-note
 
   clang_analyzer_express(clang_analyzer_iterator_position(i)); // expected-warning{{$v.begin()}}
                                                                // expected-note@-1{{$v.begin()}}
Index: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
@@ -122,9 +122,11 @@
   void assignToContainer(CheckerContext &C, const Expr *CE, SVal RetVal,
                          const MemRegion *Cont) const;
   const NoteTag *getChangeTag(CheckerContext &C, StringRef Text,
-                              const Expr *ItEx, int64_t Amount = 0,
-                              const Expr *AmEx = nullptr) const;
+                              const Expr *ItE, SVal It1, int64_t Amount = 0,
+                              Optional<SVal> It2 = None) const;
   bool noChangeInAdvance(CheckerContext &C, SVal Iter, const Expr *CE) const;
+  const NoteTag *getInterestingnessPropagationTag(CheckerContext &C, SVal It1,
+                                                  SVal It2) const;
   void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
                   const char *Sep) const override;
 
@@ -210,7 +212,9 @@
       if (cast<CXXConstructorDecl>(Func)->isMoveConstructor()) {
         State = removeIteratorPosition(State, Arg);
       }
-      C.addTransition(State);
+      const NoteTag *InterestingTag =
+        getInterestingnessPropagationTag(C, Arg, RetVal);
+      C.addTransition(State, InterestingTag);
       return;
     }
   }
@@ -242,7 +246,9 @@
   const auto *Pos = getIteratorPosition(State, Val);
   if (Pos) {
     State = setIteratorPosition(State, Loc, *Pos);
-    C.addTransition(State);
+    const NoteTag *InterestingTag =
+      getInterestingnessPropagationTag(C, Val, Loc);
+    C.addTransition(State, InterestingTag);
   } else {
     const auto *OldPos = getIteratorPosition(State, Loc);
     if (OldPos) {
@@ -533,7 +539,9 @@
   assert(NewPos &&
          "Iterator should have position after successful advancement");
 
-  const NoteTag *ChangeTag = getChangeTag(C, "incremented", ItEx, 1);
+  const NoteTag *ChangeTag =
+    getChangeTag(C, "incremented", ItEx, Iter, 1,
+                 Postfix ? None : Optional<SVal>(RetVal));
   State = setIteratorPosition(State, Iter, *NewPos);
   State = setIteratorPosition(State, RetVal, Postfix ? *Pos : *NewPos);
   C.addTransition(State, ChangeTag);
@@ -561,7 +569,9 @@
   assert(NewPos &&
          "Iterator should have position after successful advancement");
 
-  const NoteTag *ChangeTag = getChangeTag(C, "decremented", ItEx, 1);
+  const NoteTag *ChangeTag =
+    getChangeTag(C, "decremented", ItEx, Iter, 1,
+                 Postfix ? None : Optional<SVal>(RetVal));
   State = setIteratorPosition(State, Iter, *NewPos);
   State = setIteratorPosition(State, RetVal, Postfix ? *Pos : *NewPos);
   C.addTransition(State, ChangeTag);
@@ -607,8 +617,9 @@
     if (!ChangeVal)
       ChangeText = "unchanged";
     
-    const NoteTag *ChangeTag = getChangeTag(C, ChangeText, ItEx,
-                                            std::abs(ChangeVal), AmEx);
+    const NoteTag *ChangeTag =
+      getChangeTag(C, ChangeText, ItEx, Iter, std::abs(ChangeVal),
+                   (TgtVal == RetVal) ? Optional<SVal>(RetVal) : None);
     State = setIteratorPosition(State, TgtVal, *NewPos);
     C.addTransition(State, ChangeTag);
   } else {
@@ -662,8 +673,9 @@
     if (!ChangeVal)
       ChangeText = "unchanged";
     
-    const NoteTag *ChangeTag = getChangeTag(C, ChangeText, Iterator,
-                                            std::abs(ChangeVal), AmEx);
+    const NoteTag *ChangeTag =
+      getChangeTag(C, ChangeText, Iterator, OldVal, std::abs(ChangeVal),
+                   NewVal);
 
     ProgramStateRef NewState = setIteratorPosition(State, NewVal, *NewPos);
     C.addTransition(NewState, ChangeTag);
@@ -734,19 +746,26 @@
 }
 
 const NoteTag *IteratorModeling::getChangeTag(CheckerContext &C, StringRef Text,
-                                              const Expr *ItEx, int64_t Amount,
-                                              const Expr *AmEx) const {
-  if (const auto *CCE = dyn_cast<CXXConstructExpr>(ItEx)) {
-    ItEx = CCE->getArg(0);
+                                              const Expr *ItE, SVal It1,
+                                              int64_t Amount,
+                                              Optional<SVal> It2) const {
+  if (const auto *CCE = dyn_cast<CXXConstructExpr>(ItE)) {
+    ItE = CCE->getArg(0);
   }
 
   StringRef Name;
-  if (const auto *DRE = dyn_cast<DeclRefExpr>(ItEx->IgnoreParenCasts())) {
+  if (const auto *DRE = dyn_cast<DeclRefExpr>(ItE->IgnoreParenCasts())) {
     Name = DRE->getDecl()->getName();
   }
 
-  return C.getNoteTag(
-      [Text, Name, Amount, AmEx](PathSensitiveBugReport &BR) -> std::string {
+  return C.getNoteTag([Text, Name, Amount, It1,
+                       It2](PathSensitiveBugReport &BR) -> std::string {
+    if (It2 && BR.isInteresting(*It2))
+      BR.markInteresting(It1);
+
+    if (!BR.isInteresting(It1))
+      return "";
+
     SmallString<256> Msg;
     llvm::raw_svector_ostream Out(Msg);
     Out << "Iterator " << (!Name.empty() ? ("'" + Name.str() + "' ") : "")
@@ -754,13 +773,30 @@
     if (Amount) {
       Out << " by " << Amount;
     }
-    if (AmEx) {
-      bugreporter::trackExpressionValue(BR.getErrorNode(), AmEx, BR);
-    }
     return std::string(Out.str());
   });
 }
 
+// Propagate interestingness between iterators upon their assignments. This
+// is essential for tracking all the changes of an iterator from the beginning
+// to the bug location.
+//
+// Example: i = ++j;
+//
+// If `j` is affected by a bug, then this function ensures that `i` is tracked
+// further up along the path (using `NoteTags`).
+
+const NoteTag *
+IteratorModeling::getInterestingnessPropagationTag(CheckerContext &C,
+                                                   SVal It1, SVal It2) const {
+  return C.getNoteTag([It1, It2](PathSensitiveBugReport &BR) -> std::string {
+    if (BR.isInteresting(It2))
+      BR.markInteresting(It1);
+
+    return "";
+  });
+}
+
 void IteratorModeling::printState(raw_ostream &Out, ProgramStateRef State,
                                   const char *NL, const char *Sep) const {
   auto SymbolMap = State->get<IteratorSymbolMap>();
Index: clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp
@@ -88,14 +88,30 @@
   }
 
   auto State = C.getState();
-  SVal V = C.getSVal(CE->getArg(0));
-  const auto *Pos = getIteratorPosition(State, V);
+  SVal Iter = C.getSVal(CE->getArg(0));
+  const auto *Pos = getIteratorPosition(State, Iter);
+  SVal Field = Default;
+
   if (Pos) {
-    State = State->BindExpr(CE, C.getLocationContext(), get(Pos));
-  } else {
-    State = State->BindExpr(CE, C.getLocationContext(), Default);
+    Field = get(Pos);
   }
-  C.addTransition(State);
+
+  State = State->BindExpr(CE, C.getLocationContext(), Field);
+
+  // Progpagate interestingness from the iterator's position (marked interesting
+  // by an `ExprInspection` debug call to the iterator itself.
+  const NoteTag *InterestingTag =
+      C.getNoteTag([Iter, Field](PathSensitiveBugReport &BR) -> std::string {
+        if (BR.isInteresting(Field)) {
+          BR.markInteresting(Iter);
+          if (const auto &LCV = Iter.getAs<nonloc::LazyCompoundVal>()) {
+            BR.markInteresting(LCV->getRegion());
+          }
+        }
+        return "";
+      });
+
+  C.addTransition(State, InterestingTag);
 }
 
 void DebugIteratorModeling::analyzerIteratorPosition(const CallExpr *CE,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to