brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · dfb4b9e Raw
101 lines · cpp
1// RUN: %check_clang_tidy %s bugprone-inaccurate-erase %t2 3namespace std {4template <typename T> struct vec_iterator {5  T ptr;6  vec_iterator operator++(int);7 8  template <typename X>9  vec_iterator(const vec_iterator<X> &); // Omit enable_if<...>.10};11 12template <typename T> struct vector {13  typedef vec_iterator<T*> iterator;14 15  iterator begin();16  iterator end();17 18  void erase(iterator);19  void erase(iterator, iterator);20};21 22template <typename T> struct vector_with_const_iterator {23  typedef vec_iterator<T*> iterator;24  typedef vec_iterator<const T*> const_iterator;25 26  iterator begin();27  iterator end();28 29  void erase(const_iterator);30  void erase(const_iterator, const_iterator);31};32 33template <typename FwIt, typename T>34FwIt remove(FwIt begin, FwIt end, const T &val);35 36template <typename FwIt, typename Func>37FwIt remove_if(FwIt begin, FwIt end, Func f);38 39template <typename FwIt> FwIt unique(FwIt begin, FwIt end);40 41template <typename T> struct unique_ptr {};42} // namespace std43 44struct custom_iter {};45struct custom_container {46  void erase(...);47  custom_iter begin();48  custom_iter end();49};50 51template <typename T> void g() {52  T t;53  t.erase(std::remove(t.begin(), t.end(), 10));54  // CHECK-FIXES: t.erase(std::remove(t.begin(), t.end(), 10));55 56  std::vector<int> v;57  v.erase(remove(v.begin(), v.end(), 10));58  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one59  // CHECK-FIXES: v.erase(remove(v.begin(), v.end(), 10), v.end());60}61 62#define ERASE(x, y) x.erase(remove(x.begin(), x.end(), y))63// CHECK-FIXES: #define ERASE(x, y) x.erase(remove(x.begin(), x.end(), y))64 65int main() {66  std::vector<int> v;67 68  v.erase(remove(v.begin(), v.end(), 10));69  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one item even when multiple items should be removed [bugprone-inaccurate-erase]70  // CHECK-FIXES: v.erase(remove(v.begin(), v.end(), 10), v.end());71  v.erase(remove(v.begin(), v.end(), 20), v.end());72 73  auto *p = &v;74  p->erase(remove(p->begin(), p->end(), 11));75  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one76  // CHECK-FIXES: p->erase(remove(p->begin(), p->end(), 11), p->end());77 78  std::vector_with_const_iterator<int> v2;79  v2.erase(remove(v2.begin(), v2.end(), 12));80  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one81  // CHECK-FIXES: v2.erase(remove(v2.begin(), v2.end(), 12), v2.end());82 83  // Fix is not trivial.84  auto it = v.end();85  v.erase(remove(v.begin(), it, 10));86  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one87  // CHECK-FIXES: v.erase(remove(v.begin(), it, 10));88 89  g<std::vector<int>>();90  g<custom_container>();91 92  ERASE(v, 15);93  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: this call will remove at most one94  // CHECK-FIXES: ERASE(v, 15);95 96  std::vector<std::unique_ptr<int>> vupi;97  auto iter = vupi.begin();98  vupi.erase(iter++);99  // CHECK-FIXES: vupi.erase(iter++);100}101