summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp')
-rw-r--r--clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp85
1 files changed, 83 insertions, 2 deletions
diff --git a/clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp b/clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
index fcd5a96eb66..f76d84bb97a 100644
--- a/clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
+++ b/clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp
@@ -1,9 +1,27 @@
-// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm --
+// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm -- --std=c++11
namespace std {
typedef int size_t;
+template<class E> class initializer_list {
+public:
+ using value_type = E;
+ using reference = E&;
+ using const_reference = const E&;
+ using size_type = size_t;
+ using iterator = const E*;
+ using const_iterator = const E*;
+ initializer_list();
+ size_t size() const; // number of elements
+ const E* begin() const; // first element
+ const E* end() const; // one past the last element
+};
+
+// initializer list range access
+template<class E> const E* begin(initializer_list<E> il);
+template<class E> const E* end(initializer_list<E> il);
+
template <class T>
class vector {
public:
@@ -23,9 +41,24 @@ class vector {
size_t size();
const_reference operator[] (size_type) const;
reference operator[] (size_type);
+
+ const_iterator begin() const;
+ const_iterator end() const;
};
} // namespace std
+class Foo {
+ public:
+ explicit Foo(int);
+};
+
+class Bar {
+ public:
+ Bar(int);
+};
+
+int Op(int);
+
void f(std::vector<int>& t) {
{
std::vector<int> v;
@@ -85,7 +118,38 @@ void f(std::vector<int>& t) {
v.push_back(t[i]);
} // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
}
-
+ {
+ std::vector<int> v;
+ // CHECK-FIXES: v.reserve(t.size());
+ for (const auto &e : t) {
+ v.push_back(e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ }
+ {
+ std::vector<int> v;
+ // CHECK-FIXES: v.reserve(t.size());
+ for (const auto &e : t) {
+ v.push_back(Op(e));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ }
+ {
+ std::vector<Foo> v;
+ // CHECK-FIXES: v.reserve(t.size());
+ for (const auto &e : t) {
+ v.push_back(Foo(e));
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ }
+ {
+ std::vector<Bar> v;
+ // CHECK-FIXES: v.reserve(t.size());
+ for (const auto &e : t) {
+ v.push_back(e);
+ // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called
+ }
+ }
// ---- Non-fixed Cases ----
{
std::vector<int> v;
@@ -181,4 +245,21 @@ void f(std::vector<int>& t) {
v.push_back(t[i]);
}
}
+ {
+ std::vector<int> v;
+ // initializer_list should not trigger the check.
+ for (int e : {1, 2, 3, 4, 5}) {
+ v.push_back(e);
+ }
+ }
+ {
+ std::vector<int> v;
+ std::vector<int>* v2 = &t;
+ // We only support detecting the range init expression which references
+ // container directly.
+ // Complex range init expressions like `*v2` is not supported.
+ for (const auto &e : *v2) {
+ v.push_back(e);
+ }
+ }
}
OpenPOWER on IntegriCloud