From 45ca9b705cb814c4b7ed71cd7d5a64efe5da5d07 Mon Sep 17 00:00:00 2001 From: Adam Balogh Date: Sat, 13 Oct 2018 10:24:48 +0000 Subject: [PATCH] [Analyzer] Iterator Checker - Part 10: Tests for iterators passed as parameter In earlier Clang Static Analyzer versions `check::Bind() was not invoked for parameter passing, so we needed a trick which is not needed anymore. However add the tests to ensure its working. Differential Revision: https::/reviews.llvm.org/D32906 llvm-svn: 344443 --- clang/test/Analysis/iterator-range.cpp | 22 +++++++++++++++++++++ clang/test/Analysis/mismatched-iterator.cpp | 13 ++++++++++++ 2 files changed, 35 insertions(+) diff --git a/clang/test/Analysis/iterator-range.cpp b/clang/test/Analysis/iterator-range.cpp index 32e3495a12b6..78cdb095c4d1 100644 --- a/clang/test/Analysis/iterator-range.cpp +++ b/clang/test/Analysis/iterator-range.cpp @@ -97,6 +97,28 @@ void copy_and_increase3(const std::vector &v) { *i2; // expected-warning{{Iterator accessed outside of its range}} } +template +InputIterator nonStdFind(InputIterator first, InputIterator last, + const T &val) { + for (auto i = first; i != last; ++i) { + if (*i == val) { + return i; + } + } + return last; +} + +void good_non_std_find(std::vector &V, int e) { + auto first = nonStdFind(V.begin(), V.end(), e); + if (V.end() != first) + *first; // no-warning +} + +void bad_non_std_find(std::vector &V, int e) { + auto first = nonStdFind(V.begin(), V.end(), e); + *first; // expected-warning{{Iterator accessed outside of its range}} +} + void tricky(std::vector &V, int e) { const auto first = V.begin(); const auto comp1 = (first != V.end()), comp2 = (first == V.end()); diff --git a/clang/test/Analysis/mismatched-iterator.cpp b/clang/test/Analysis/mismatched-iterator.cpp index 7910b77c0b9a..23f54d3f796a 100644 --- a/clang/test/Analysis/mismatched-iterator.cpp +++ b/clang/test/Analysis/mismatched-iterator.cpp @@ -144,6 +144,19 @@ void bad_overwrite(std::vector &v1, std::vector &v2, int n) { v1.insert(i, n); // expected-warning{{Container accessed using foreign iterator argument}} } +template +bool is_cend(Container cont, Iterator it) { + return it == cont.cend(); +} + +void good_empty(std::vector &v) { + is_cend(v, v.cbegin()); // no-warning +} + +void bad_empty(std::vector &v1, std::vector &v2) { + is_cend(v1, v2.cbegin()); // expected-warning@-8{{Iterators of different containers used where the same container is expected}} +} + void good_move(std::vector &v1, std::vector &v2) { const auto i0 = ++v2.cbegin(); v1 = std::move(v2);