baloghadamsoftware created this revision.
baloghadamsoftware added reviewers: NoQ, Szelethus.
baloghadamsoftware added a project: clang.
Herald added subscribers: martong, steakhal, Charusso, gamesh411, donat.nagy, 
mikhail.ramalho, a.sidorin, rnkovacs, szepet, xazax.hun, whisperity.
baloghadamsoftware added a parent revision: D74541: [Analyzer] Use note tags to 
track iterator increments and decrements.

If an error happens which is related to some iterators the Iterator Modeling 
checker adds note tags to all the iterator operations along the bug path. This 
may be disturbing if there are other iterators beside the ones which are 
affected by the bug. This patch restricts the note tags to only the affected 
iterators and adjust the debug checkers to be able to test this change.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75677

Files:
  clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp
  clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
  clang/test/Analysis/iterator-modelling.cpp

Index: clang/test/Analysis/iterator-modelling.cpp
===================================================================
--- clang/test/Analysis/iterator-modelling.cpp
+++ clang/test/Analysis/iterator-modelling.cpp
@@ -81,7 +81,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{{$v.begin() + 1}}
                                                                //expected-note@-1{{$v.begin() + 1}}
@@ -94,7 +94,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{{$v.end() - 1}}
                                                                //expected-note@-1{{$v.end() - 1}}
@@ -164,7 +164,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
-  auto i2 = i1 + 2; // expected-note 2{{Iterator 'i1' incremented by 2}}
+  auto i2 = i1 + 2; // expected-note{{Iterator 'i1' incremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -177,7 +177,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
 
-  auto i2 = i1 + (-2); // expected-note 2{{Iterator 'i1' decremented by 2}}
+  auto i2 = i1 + (-2); // expected-note{{Iterator 'i1' decremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -190,7 +190,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
 
-  auto i2 = i1 - 2;  // expected-note 2{{Iterator 'i1' decremented by 2}}
+  auto i2 = i1 - 2; // expected-note{{Iterator 'i1' decremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -203,7 +203,7 @@
 
   clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
 
-  auto i2 = i1 - (-2); // expected-note 2{{Iterator 'i1' incremented by 2}}
+  auto i2 = i1 - (-2); // expected-note{{Iterator 'i1' incremented by 2}}
 
   clang_analyzer_eval(clang_analyzer_iterator_container(i2) == &v); // expected-warning{{TRUE}}
                                                                     // expected-note@-1{{TRUE}}
@@ -217,7 +217,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{{$v.begin() + 1}}
                                                                 //expected-note@-1{{$v.begin() + 1}}
@@ -231,7 +231,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{{$v.begin()}}
                                                                 //expected-note@-1{{$v.begin()}}
@@ -245,7 +245,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{{$v.end() - 1}}
                                                                 //expected-note@-1{{$v.end() - 1}}
@@ -259,7 +259,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{{$v.end()}}
                                                                 //expected-note@-1{{$v.end()}}
@@ -316,7 +316,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()");
@@ -343,7 +342,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()");
 
@@ -369,7 +367,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()");
 
@@ -515,7 +512,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()");
@@ -541,7 +538,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()");
@@ -566,7 +563,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()");
@@ -592,7 +588,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()");
@@ -618,7 +614,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()");
@@ -643,7 +639,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()");
@@ -669,7 +664,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()");
@@ -694,7 +688,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()");
@@ -718,7 +711,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()");
@@ -769,7 +761,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()");
@@ -838,7 +829,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()");
@@ -885,7 +875,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()");
@@ -910,7 +900,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()");
@@ -935,7 +925,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()");
@@ -989,7 +979,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()");
@@ -1041,7 +1031,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()");
@@ -1066,7 +1056,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()");
@@ -1111,7 +1101,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()");
@@ -1153,7 +1142,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()");
@@ -1174,7 +1162,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()");
@@ -1216,7 +1204,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()");
@@ -1254,7 +1241,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()");
@@ -1273,7 +1259,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()");
@@ -1322,7 +1307,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()");
@@ -1404,7 +1389,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()");
@@ -1456,7 +1441,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()");
@@ -1481,7 +1466,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()");
@@ -1525,7 +1510,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()");
@@ -1567,7 +1551,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()");
@@ -1588,7 +1571,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()");
@@ -1629,7 +1612,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()");
@@ -1666,7 +1648,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()");
@@ -1685,7 +1666,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()");
@@ -1735,7 +1715,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()");
@@ -1798,7 +1778,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()");
@@ -1821,7 +1801,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()");
@@ -1867,7 +1846,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()");
@@ -1893,7 +1871,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()");
@@ -1912,7 +1889,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()");
@@ -1954,7 +1930,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()");
@@ -1983,7 +1958,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()");
@@ -2002,7 +1976,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()");
@@ -2040,7 +2013,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()");
@@ -2072,9 +2044,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()");
@@ -2103,11 +2075,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()");
@@ -2236,8 +2207,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()}}
@@ -2251,8 +2222,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
@@ -105,6 +105,8 @@
   const NoteTag *getChangeTag(CheckerContext &C, StringRef Text,
                               const Expr *ItE, SVal It1, int64_t Amount = 0,
                               SVal It2 = UndefinedVal()) 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;
 public:
@@ -215,7 +217,10 @@
         if (cast<CXXConstructorDecl>(Func)->isMoveConstructor()) {
           State = removeIteratorPosition(State, Call.getArgSVal(0));
         }
-        C.addTransition(State);
+        const NoteTag *InterestingTag =
+          getInterestingnessPropagationTag(C, Call.getArgSVal(0),
+                                           Call.getReturnValue());
+        C.addTransition(State, InterestingTag);
         return;
       }
     }
@@ -243,7 +248,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) {
@@ -263,7 +270,9 @@
   if (!Pos)
     return;
   State = setIteratorPosition(State, NewVal, *Pos);
-  C.addTransition(State);
+  const NoteTag *InterestingTag =
+    getInterestingnessPropagationTag(C, OldVal, NewVal);
+  C.addTransition(State, InterestingTag);
 }
 
 void IteratorModeling::checkLiveSymbols(ProgramStateRef State,
@@ -525,6 +534,32 @@
 
   return C.getNoteTag([Text, Name, Amount, It1, It2](BugReport &BR)
                       -> std::string {
+      auto *PSBR = dyn_cast<PathSensitiveBugReport>(&BR);
+      if (!PSBR)
+        return "";
+
+      if (PSBR->isInteresting(It2)) {
+        PSBR->markInteresting(It1);
+        if (const auto &LCV1 = It1.getAs<nonloc::LazyCompoundVal>()) {
+          PSBR->markInteresting(LCV1->getRegion());
+        }
+      } else if (const auto &LCV2 = It2.getAs<nonloc::LazyCompoundVal>()) {
+        if (PSBR->isInteresting(LCV2->getRegion())) {
+          PSBR->markInteresting(It1);
+          if (const auto &LCV1 = It1.getAs<nonloc::LazyCompoundVal>()) {
+            PSBR->markInteresting(LCV1->getRegion());
+          }
+        }
+      }
+      
+      if (!PSBR->isInteresting(It1)) {
+        const auto &LCV1 = It1.getAs<nonloc::LazyCompoundVal>();
+        if (!LCV1)
+          return "";
+        if (!PSBR->isInteresting(LCV1->getRegion()))
+          return "";
+      }
+
       SmallString<256> Msg;
       llvm::raw_svector_ostream Out(Msg);
       Out << "Iterator " << (!Name.empty() ? ("'" + Name.str() + "' ") : "" )
@@ -536,6 +571,33 @@
     });
 }
 
+const NoteTag *
+IteratorModeling::getInterestingnessPropagationTag(CheckerContext &C,
+                                                   SVal It1, SVal It2) const {
+  return C.getNoteTag([It1, It2](BugReport &BR)
+                      -> std::string {
+      auto *PSBR = dyn_cast<PathSensitiveBugReport>(&BR);
+      if (!PSBR)
+        return "";
+
+      if (PSBR->isInteresting(It2)) {
+        PSBR->markInteresting(It1);
+        if (const auto &LCV1 = It1.getAs<nonloc::LazyCompoundVal>()) {
+          PSBR->markInteresting(LCV1->getRegion());
+        }
+      } else if (const auto &LCV2 = It2.getAs<nonloc::LazyCompoundVal>()) {
+        if (PSBR->isInteresting(LCV2->getRegion())) {
+          PSBR->markInteresting(It1);
+          if (const auto &LCV1 = It1.getAs<nonloc::LazyCompoundVal>()) {
+            PSBR->markInteresting(LCV1->getRegion());
+          }
+        }
+      }
+      
+      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/ExprInspectionChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -50,9 +50,11 @@
   typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
                                                  CheckerContext &C) const;
 
-  ExplodedNode *reportBug(llvm::StringRef Msg, CheckerContext &C) const;
+  ExplodedNode *reportBug(llvm::StringRef Msg, CheckerContext &C,
+                          SVal ExprVal = UndefinedVal()) const;
   ExplodedNode *reportBug(llvm::StringRef Msg, BugReporter &BR,
-                          ExplodedNode *N) const;
+                          ExplodedNode *N,
+                          SVal ExprVal = UndefinedVal()) const;
 
 public:
   bool evalCall(const CallEvent &Call, CheckerContext &C) const;
@@ -134,22 +136,28 @@
 }
 
 ExplodedNode *ExprInspectionChecker::reportBug(llvm::StringRef Msg,
-                                               CheckerContext &C) const {
+                                               CheckerContext &C,
+                                               SVal ExprVal) const {
   ExplodedNode *N = C.generateNonFatalErrorNode();
-  reportBug(Msg, C.getBugReporter(), N);
+  reportBug(Msg, C.getBugReporter(), N, ExprVal);
   return N;
 }
 
 ExplodedNode *ExprInspectionChecker::reportBug(llvm::StringRef Msg,
                                                BugReporter &BR,
-                                               ExplodedNode *N) const {
+                                               ExplodedNode *N,
+                                               SVal ExprVal) const {
   if (!N)
     return nullptr;
 
   if (!BT)
     BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
 
-  BR.emitReport(std::make_unique<PathSensitiveBugReport>(*BT, Msg, N));
+  auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
+  if (!ExprVal.isUndef()) {
+    R->markInteresting(ExprVal);
+  }
+  BR.emitReport(std::move(R));
   return N;
 }
 
@@ -396,7 +404,8 @@
     return;
   }
 
-  SymbolRef Sym = C.getSVal(CE->getArg(0)).getAsSymbol();
+  SVal ArgVal = C.getSVal(CE->getArg(0));
+  SymbolRef Sym = ArgVal.getAsSymbol();
   if (!Sym) {
     reportBug("Not a symbol", C);
     return;
@@ -409,7 +418,7 @@
     return;
   }
 
-  reportBug(*Str, C);
+  reportBug(*Str, C, ArgVal);
 }
 
 void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
Index: clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp
+++ clang/lib/StaticAnalyzer/Checkers/DebugIteratorModeling.cpp
@@ -90,12 +90,27 @@
   auto State = C.getState();
   SVal V = C.getSVal(CE->getArg(0));
   const auto *Pos = getIteratorPosition(State, V);
+  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);
+
+  const NoteTag *InterestingTag =
+    C.getNoteTag([V, Field](BugReport &BR) -> std::string {
+        auto *PSBR = dyn_cast<PathSensitiveBugReport>(&BR);
+        if (PSBR && PSBR->isInteresting(Field)) {
+          PSBR->markInteresting(V);
+          if (const auto &LCV = V.getAs<nonloc::LazyCompoundVal>()) {
+            PSBR->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