diff options
author | dim <dim@FreeBSD.org> | 2011-05-02 19:39:53 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-05-02 19:39:53 +0000 |
commit | 110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (patch) | |
tree | 64a10f4c4154739d4a8191d7e1b52ce497f4ebd6 /test/Analysis/iterators.cpp | |
parent | a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51 (diff) | |
download | FreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.zip FreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.tar.gz |
Vendor import of clang trunk r130700:
http://llvm.org/svn/llvm-project/cfe/trunk@130700
Diffstat (limited to 'test/Analysis/iterators.cpp')
-rw-r--r-- | test/Analysis/iterators.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/test/Analysis/iterators.cpp b/test/Analysis/iterators.cpp new file mode 100644 index 0000000..c3416f5 --- /dev/null +++ b/test/Analysis/iterators.cpp @@ -0,0 +1,105 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.experimental.Iterators -verify %s +// XFAIL: win32 + +#include <vector> + +void fum(std::vector<int>::iterator t); + +void foo1() +{ + // iterators that are defined but not initialized + std::vector<int>::iterator it2; + fum(it2); // expected-warning{{Use of iterator that is not defined}} + *it2; // expected-warning{{Use of iterator that is not defined}} + + std::vector<int> v, vv; + std::vector<int>::iterator it = v.begin(); + fum(it); // no-warning + *it; // no-warning + // a valid iterator plus an integer is still valid + std::vector<int>::iterator et = it + 3; + while(it != et) { // no-warning + if (*it == 0) // no-warning + *it = 1; // no-warning + } + // iterators from different instances Cannot be compared + et = vv.end(); + while(it != et) // expected-warning{{Cannot compare iterators from different containers}} + ; + + for( std::vector<int>::iterator it = v.begin(); it != v.end(); it++ ) { // no-warning + if (*it == 1) // no-warning + *it = 0; // no-warning + } + + // copying a valid iterator results in a valid iterator + et = it; // no-warning + *et; // no-warning + + // any combo of valid iterator plus a constant is still valid + et = it + 2; // no-warning + *et; // no-warning + et = 2 + it; // no-warning + *et; // no-warning + et = 2 + 4 + it; // no-warning + *et; // no-warning + + // calling insert invalidates unless assigned to as result, but still + // invalidates other iterators on the same instance + it = v.insert( it, 1 ); // no-warning + *et; // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'}} + ++it; // no-warning + + // calling erase invalidates the iterator + v.erase(it); // no-warning + et = it + 2; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} + et = 2 + it + 2; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} + et = 2 + it; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} + ++it; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} + it++; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} + *it; // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} + it = v.insert( it, 1 ); // expected-warning{{Attempt to use an iterator made invalid by call to 'erase'}} + // now valid after return from insert + *it; // no-warning +} + +// work with using namespace +void foo2() +{ + using namespace std; + + vector<int> v; + vector<int>::iterator it = v.begin(); + *it; // no-warning + v.insert( it, 1 ); // no-warning + *it; // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'}} + it = v.insert( it, 1 ); // expected-warning{{Attempt to use an iterator made invalid by call to 'insert'}} + *it; // no-warning +} + +// using reserve eliminates some warnings +void foo3() +{ + std::vector<long> v; + std::vector<long>::iterator b = v.begin(); + v.reserve( 100 ); + + // iterator assigned before the reserve is still invalidated + *b; // expected-warning{{Attempt to use an iterator made invalid by call to 'reserve'}} + b = v.begin(); + v.insert( b, 1 ); // no-warning + + // iterator after assignment is still valid (probably) + *b; // no-warning +} + +// check on copying one iterator to another +void foo4() +{ + std::vector<float> v, vv; + std::vector<float>::iterator it = v.begin(); + *it; // no-warning + v = vv; + *it; // expected-warning{{Attempt to use an iterator made invalid by copying another container to its container}} +} + |