diff options
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.cpp | 183 |
1 files changed, 183 insertions, 0 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 new file mode 100644 index 00000000000..f51c4690a25 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/performance-inefficient-vector-operation.cpp @@ -0,0 +1,183 @@ +// RUN: %check_clang_tidy %s performance-inefficient-vector-operation %t -- -format-style=llvm -- + +typedef int size_t; + +namespace std { +template <class T> +class vector { + public: + typedef T* iterator; + typedef const T* const_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef size_t size_type; + + explicit vector(); + explicit vector(size_type n); + + void push_back(const T& val); + void reserve(size_t n); + void resize(size_t n); + + size_t size(); + const_reference operator[] (size_type) const; + reference operator[] (size_type); +}; +} // namespace std + +void f(std::vector<int>& t) { + { + std::vector<int> v; + // CHECK-FIXES: v.reserve(10); + for (int i = 0; i < 10; ++i) + v.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called inside a loop; consider pre-allocating the vector capacity before the loop + } + { + std::vector<int> v; + // CHECK-FIXES: v.reserve(10); + for (int i = 0; i < 10; i++) + v.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called + } + { + std::vector<int> v; + // CHECK-FIXES: v.reserve(10); + for (int i = 0; i < 10; ++i) + v.push_back(0); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called + } + { + std::vector<int> v; + // CHECK-FIXES: v.reserve(5); + for (int i = 0; i < 5; ++i) { + v.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called + } + // CHECK-FIXES-NOT: v.reserve(10); + for (int i = 0; i < 10; ++i) { + // No fix for this loop as we encounter the prior loops. + v.push_back(i); + } + } + { + std::vector<int> v; + std::vector<int> v2; + v2.reserve(3); + // CHECK-FIXES: v.reserve(10); + for (int i = 0; i < 10; ++i) + v.push_back(i); + // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called + } + { + std::vector<int> v; + // CHECK-FIXES: v.reserve(t.size()); + for (size_t i = 0; i < t.size(); ++i) { + 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() - 1); + for (size_t i = 0; i < t.size() - 1; ++i) { + v.push_back(t[i]); + } // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'push_back' is called + } + + // ---- Non-fixed Cases ---- + { + std::vector<int> v; + v.reserve(20); + // CHECK-FIXES-NOT: v.reserve(10); + // There is a "reserve" call already. + for (int i = 0; i < 10; ++i) { + v.push_back(i); + } + } + { + std::vector<int> v; + v.reserve(5); + // CHECK-FIXES-NOT: v.reserve(10); + // There is a "reserve" call already. + for (int i = 0; i < 10; ++i) { + v.push_back(i); + } + } + { + std::vector<int> v; + v.resize(5); + // CHECK-FIXES-NOT: v.reserve(10); + // There is a ref usage of v before the loop. + for (int i = 0; i < 10; ++i) { + v.push_back(i); + } + } + { + std::vector<int> v; + v.push_back(0); + // CHECK-FIXES-NOT: v.reserve(10); + // There is a ref usage of v before the loop. + for (int i = 0; i < 10; ++i) { + v.push_back(i); + } + } + { + std::vector<int> v; + f(v); + // CHECK-FIXES-NOT: v.reserve(10); + // There is a ref usage of v before the loop. + for (int i = 0; i < 10; ++i) { + v.push_back(i); + } + } + { + std::vector<int> v(20); + // CHECK-FIXES-NOT: v.reserve(10); + // v is not constructed with default constructor. + for (int i = 0; i < 10; ++i) { + v.push_back(i); + } + } + { + std::vector<int> v; + // CHECK-FIXES-NOT: v.reserve(10); + // For-loop is not started with 0. + for (int i = 1; i < 10; ++i) { + v.push_back(i); + } + } + { + std::vector<int> v; + // CHECK-FIXES-NOT: v.reserve(t.size()); + // v isn't referenced in for-loop body. + for (size_t i = 0; i < t.size(); ++i) { + t.push_back(i); + } + } + { + std::vector<int> v; + int k; + // CHECK-FIXES-NOT: v.reserve(10); + // For-loop isn't a fixable loop. + for (size_t i = 0; k < 10; ++i) { + v.push_back(t[i]); + } + } + { + std::vector<int> v; + // CHECK-FIXES-NOT: v.reserve(i + 1); + // The loop end expression refers to the loop variable i. + for (int i = 0; i < i + 1; i++) + v.push_back(i); + } + { + std::vector<int> v; + int k; + // CHECK-FIXES-NOT: v.reserve(10); + // For-loop isn't a fixable loop. + for (size_t i = 0; i < 10; ++k) { + v.push_back(t[i]); + } + } +} |

