[PATCH] D76361: [Analyzer] Iterator Modeling - Model `std::advance()`, `std::prev()` and `std::next()`

2020-03-23 Thread Balogh, Ádám via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
baloghadamsoftware marked 4 inline comments as done.
Closed by commit rG60bad941a1c1: [Analyzer] Iterator Modeling - Model 
`std::advance()`, `std::prev()` and `std… (authored by baloghadamsoftware).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76361

Files:
  clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
  clang/test/Analysis/Inputs/system-header-simulator-cxx.h
  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
@@ -2,6 +2,12 @@
 
 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
 
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=0 %s -verify
+
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=1 %s -verify
+
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=2 %s -verify
+
 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true %s 2>&1 | FileCheck %s
 
 #include "Inputs/system-header-simulator-cxx.h"
@@ -233,6 +239,68 @@
   clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 1}}
 }
 
+/// std::advance(), std::prev(), std::next()
+
+void std_advance_minus(const std::vector ) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  std::advance(i, -1);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}}
+}
+
+void std_advance_plus(const std::vector ) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  std::advance(i, 1);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}}
+}
+
+void std_prev(const std::vector ) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto j = std::prev(i);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 1}}
+}
+
+void std_prev2(const std::vector ) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto j = std::prev(i, 2);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 2}}
+}
+
+void std_next(const std::vector ) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto j = std::next(i);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 1}}
+}
+
+void std_next2(const std::vector ) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto j = std::next(i, 2);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 2}}
+}
+
 
 ///
 /// C O N T A I N E R   A S S I G N M E N T S
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
@@ -757,31 +757,66 @@
 }
 
 template 
-void __advance (BidirectionalIterator& it, Distance n,
-std::bidirectional_iterator_tag) {
+void __advance(BidirectionalIterator& it, Distance n,
+   std::bidirectional_iterator_tag)
+#if !defined(STD_ADVANCE_INLINE_LEVEL) || STD_ADVANCE_INLINE_LEVEL > 2
+{
   if (n >= 0) while(n-- > 0) ++it; else while (n++<0) --it;
 }
+#else
+;
+#endif
 
 template 
-void __advance (RandomAccessIterator& it, Distance n,
-std::random_access_iterator_tag) {
+void __advance(RandomAccessIterator& it, Distance n,
+   

[PATCH] D76361: [Analyzer] Iterator Modeling - Model `std::advance()`, `std::prev()` and `std::next()`

2020-03-20 Thread Gabor Marton via Phabricator via cfe-commits
martong accepted this revision.
martong added a comment.
This revision is now accepted and ready to land.

LGTM!




Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:221
+if (Handler) {
+  if (!C.wasInlined) {
+if (Call.getNumArgs() > 1) {

baloghadamsoftware wrote:
> martong wrote:
> > Perhaps putting this hunk into a separate function or lambda could decrease 
> > the nesting level, b/c you could have an early return if there is no 
> > `Handler`.
> Early return is not possible because the execution must continue if the is no 
> handler. However, I refactored `checkPostCall` now, the handling of both 
> overloaded operators and advance-like functions are moved to separate 
> functions.
Thanks, that's much better structured this way.



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:559
 
+bool IteratorModeling::noChangeInPosition(CheckerContext , SVal Iter,
+  const Expr *CE) const {

baloghadamsoftware wrote:
> martong wrote:
> > Some comments would be helpful here. Also, should we use this function only 
> > with `advance()` or it could be useful perhaps in other context?
> I renamed the function and added a short comment. Is it OK?
Yeah, looks ok.



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:571
+  const ExplodedNode *N = C.getPredecessor();
+  while (N) {
+ProgramPoint PP = N->getLocation();

baloghadamsoftware wrote:
> martong wrote:
> > I have a rough presumption that this hunk is a general pattern to get the 
> > previous node for the previous iterator position. So perhaps it would be 
> > useful as a standalone free/static member function too?
> I moved this to a standalone function and named it accordingly.
Thanks, it's easier to read the code this way.


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

https://reviews.llvm.org/D76361



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D76361: [Analyzer] Iterator Modeling - Model `std::advance()`, `std::prev()` and `std::next()`

2020-03-20 Thread Balogh, Ádám via Phabricator via cfe-commits
baloghadamsoftware marked 9 inline comments as done.
baloghadamsoftware added a comment.

In D76361#1929483 , @martong wrote:

> I suppose we could get this strange behavior with `std::distance` too? Would 
> it be worth to handle that as well here?


Modeling of `std::distance()` is planned after we model the size of the 
container properly.




Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:221
+if (Handler) {
+  if (!C.wasInlined) {
+if (Call.getNumArgs() > 1) {

martong wrote:
> Perhaps putting this hunk into a separate function or lambda could decrease 
> the nesting level, b/c you could have an early return if there is no 
> `Handler`.
Early return is not possible because the execution must continue if the is no 
handler. However, I refactored `checkPostCall` now, the handling of both 
overloaded operators and advance-like functions are moved to separate functions.



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:222
+  if (!C.wasInlined) {
+if (Call.getNumArgs() > 1) {
+  (this->**Handler)(C, OrigExpr, Call.getReturnValue(),

martong wrote:
> Maybe a comment could be helpful here about the common signature of the 
> prev/next functions. Like:
> ```
> advanceFun ( It it, Distance n = 1 )
> ```
> By the way, can we call `std::advance` with one argument?
I added them to the map.



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:238
+  if (IdInfo) {
+if (IdInfo->getName() == "advance") {
+  if (noChangeInPosition(C, Call.getArgSVal(0), OrigExpr)) {

martong wrote:
> Should this be `__advance`?
No. `__advance()` is non-standard, I cannot rely on it. If the function was 
`std::advance()`, it was inlined, but still did not change the iterator's 
position means that it did not do its job. Probably the function it calls 
inside (which could be `__advance()` in most implementations) was not inlined. 
In this case we model the behavior of `std::advance()` explicitely.



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:559
 
+bool IteratorModeling::noChangeInPosition(CheckerContext , SVal Iter,
+  const Expr *CE) const {

martong wrote:
> Some comments would be helpful here. Also, should we use this function only 
> with `advance()` or it could be useful perhaps in other context?
I renamed the function and added a short comment. Is it OK?



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:571
+  const ExplodedNode *N = C.getPredecessor();
+  while (N) {
+ProgramPoint PP = N->getLocation();

martong wrote:
> I have a rough presumption that this hunk is a general pattern to get the 
> previous node for the previous iterator position. So perhaps it would be 
> useful as a standalone free/static member function too?
I moved this to a standalone function and named it accordingly.


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

https://reviews.llvm.org/D76361



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D76361: [Analyzer] Iterator Modeling - Model `std::advance()`, `std::prev()` and `std::next()`

2020-03-20 Thread Balogh, Ádám via Phabricator via cfe-commits
baloghadamsoftware updated this revision to Diff 251567.
baloghadamsoftware added a comment.

Updated according to the comments and automatic formatting suggestions.


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

https://reviews.llvm.org/D76361

Files:
  clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
  clang/test/Analysis/Inputs/system-header-simulator-cxx.h
  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
@@ -2,6 +2,12 @@
 
 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
 
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=0 %s -verify
+
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=1 %s -verify
+
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=2 %s -verify
+
 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true %s 2>&1 | FileCheck %s
 
 #include "Inputs/system-header-simulator-cxx.h"
@@ -233,6 +239,68 @@
   clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 1}}
 }
 
+/// std::advance(), std::prev(), std::next()
+
+void std_advance_minus(const std::vector ) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  std::advance(i, -1);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}}
+}
+
+void std_advance_plus(const std::vector ) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  std::advance(i, 1);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}}
+}
+
+void std_prev(const std::vector ) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto j = std::prev(i);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 1}}
+}
+
+void std_prev2(const std::vector ) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto j = std::prev(i, 2);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 2}}
+}
+
+void std_next(const std::vector ) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto j = std::next(i);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 1}}
+}
+
+void std_next2(const std::vector ) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto j = std::next(i, 2);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 2}}
+}
+
 
 ///
 /// C O N T A I N E R   A S S I G N M E N T S
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
@@ -757,31 +757,66 @@
 }
 
 template 
-void __advance (BidirectionalIterator& it, Distance n,
-std::bidirectional_iterator_tag) {
+void __advance(BidirectionalIterator& it, Distance n,
+   std::bidirectional_iterator_tag)
+#if !defined(STD_ADVANCE_INLINE_LEVEL) || STD_ADVANCE_INLINE_LEVEL > 2
+{
   if (n >= 0) while(n-- > 0) ++it; else while (n++<0) --it;
 }
+#else
+;
+#endif
 
 template 
-void __advance (RandomAccessIterator& it, Distance n,
-std::random_access_iterator_tag) {
+void __advance(RandomAccessIterator& it, Distance n,
+   std::random_access_iterator_tag)
+#if !defined(STD_ADVANCE_INLINE_LEVEL) || STD_ADVANCE_INLINE_LEVEL > 2
+{
   it += n;
 }
+#else
+;
+#endif
 
 namespace std 

[PATCH] D76361: [Analyzer] Iterator Modeling - Model `std::advance()`, `std::prev()` and `std::next()`

2020-03-18 Thread Gabor Marton via Phabricator via cfe-commits
martong added inline comments.



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:221
+if (Handler) {
+  if (!C.wasInlined) {
+if (Call.getNumArgs() > 1) {

Perhaps putting this hunk into a separate function or lambda could decrease the 
nesting level, b/c you could have an early return if there is no `Handler`.



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:222
+  if (!C.wasInlined) {
+if (Call.getNumArgs() > 1) {
+  (this->**Handler)(C, OrigExpr, Call.getReturnValue(),

Maybe a comment could be helpful here about the common signature of the 
prev/next functions. Like:
```
advanceFun ( It it, Distance n = 1 )
```
By the way, can we call `std::advance` with one argument?



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:238
+  if (IdInfo) {
+if (IdInfo->getName() == "advance") {
+  if (noChangeInPosition(C, Call.getArgSVal(0), OrigExpr)) {

Should this be `__advance`?



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:559
 
+bool IteratorModeling::noChangeInPosition(CheckerContext , SVal Iter,
+  const Expr *CE) const {

Some comments would be helpful here. Also, should we use this function only 
with `advance()` or it could be useful perhaps in other context?



Comment at: clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp:571
+  const ExplodedNode *N = C.getPredecessor();
+  while (N) {
+ProgramPoint PP = N->getLocation();

I have a rough presumption that this hunk is a general pattern to get the 
previous node for the previous iterator position. So perhaps it would be useful 
as a standalone free/static member function too?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76361



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D76361: [Analyzer] Iterator Modeling - Model `std::advance()`, `std::prev()` and `std::next()`

2020-03-18 Thread Gabor Marton via Phabricator via cfe-commits
martong added a comment.

> Whenever the analyzer budget runs out just at the point where std::advance(), 
> std::prev() or std::next() is invoked the function are not inlined. This 
> results in strange behavior such as std::prev(v.end()) equals v.end(). To 
> prevent this model these functions if they were not inlined. It may also 
> happend that although std::advance() is inlined but a function it calls 
> inside (e.g. __advance() in some implementations) is not. This case is also 
> handled in this patch.

I suppose we could get this strange behavior with `std::distance` too? Would it 
be worth to handle that as well here?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76361



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D76361: [Analyzer] Iterator Modeling - Model `std::advance()`, `std::prev()` and `std::next()`

2020-03-18 Thread Balogh, Ádám via Phabricator via cfe-commits
baloghadamsoftware created this revision.
baloghadamsoftware added reviewers: NoQ, Szelethus.
baloghadamsoftware added a project: clang.
Herald added subscribers: ASDenysPetrov, martong, steakhal, Charusso, 
gamesh411, dkrupp, donat.nagy, mikhail.ramalho, a.sidorin, rnkovacs, szepet, 
xazax.hun, whisperity.
baloghadamsoftware added a comment.

Partially replacing D62895 .


Whenever the analyzer budget runs out just at the point where `std::advance()`, 
`std::prev()` or `std::next()` is invoked the function are not inlined. This 
results in strange behavior such as `std::prev(v.end())` equals `v.end()`. To 
prevent this model these functions if they were not inlined. It may also 
happend that although `std::advance()` is inlined but a function it calls 
inside (e.g. `__advance()` in some implementations) is not. This case is also 
handled in this patch.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76361

Files:
  clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
  clang/test/Analysis/Inputs/system-header-simulator-cxx.h
  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
@@ -2,6 +2,12 @@
 
 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
 
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=0 %s -verify
+
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=1 %s -verify
+
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,debug.DebugIteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true -analyzer-config c++-container-inlining=true -DINLINE=1 -DSTD_ADVANCE_INLINE_LEVEL=2 %s -verify
+
 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorModeling,debug.ExprInspection -analyzer-config aggressive-binary-operation-simplification=true %s 2>&1 | FileCheck %s
 
 #include "Inputs/system-header-simulator-cxx.h"
@@ -233,6 +239,68 @@
   clang_analyzer_express(clang_analyzer_iterator_position(i2)); //expected-warning{{$v.end() - 1}}
 }
 
+/// std::advance(), std::prev(), std::next()
+
+void std_advance_minus(const std::vector ) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  std::advance(i, -1);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.end() - 1}}
+}
+
+void std_advance_plus(const std::vector ) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  std::advance(i, 1);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(i)); //expected-warning{{$v.begin() + 1}}
+}
+
+void std_prev(const std::vector ) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto j = std::prev(i);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 1}}
+}
+
+void std_prev2(const std::vector ) {
+  auto i = v.end();
+
+  clang_analyzer_denote(clang_analyzer_container_end(v), "$v.end()");
+
+  auto j = std::prev(i, 2);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.end() - 2}}
+}
+
+void std_next(const std::vector ) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto j = std::next(i);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 1}}
+}
+
+void std_next2(const std::vector ) {
+  auto i = v.begin();
+
+  clang_analyzer_denote(clang_analyzer_container_begin(v), "$v.begin()");
+
+  auto j = std::next(i, 2);
+
+  clang_analyzer_express(clang_analyzer_iterator_position(j)); //expected-warning{{$v.begin() + 2}}
+}
+
 
 ///
 /// C O N T A I N E R   A S S I G N M E N T S
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
@@ -758,30 +758,64 @@
 
 template 
 void __advance 

[PATCH] D76361: [Analyzer] Iterator Modeling - Model `std::advance()`, `std::prev()` and `std::next()`

2020-03-18 Thread Balogh, Ádám via Phabricator via cfe-commits
baloghadamsoftware added a comment.

Partially replacing D62895 .


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D76361



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits