brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.6 KiB · 0b5ef50 Raw
353 lines · cpp
1// RUN: %check_clang_tidy %s performance-for-range-copy %t -- -- -fno-delayed-template-parsing2 3namespace std {4 5template <typename _Tp>6struct remove_reference { typedef _Tp type; };7template <typename _Tp>8struct remove_reference<_Tp&> { typedef _Tp type; };9template <typename _Tp>10struct remove_reference<_Tp&&> { typedef _Tp type; };11 12template <typename _Tp>13constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) {14  return static_cast<typename std::remove_reference<_Tp>::type &&>(__t);15}16 17} // std18 19template <typename T>20struct Iterator {21  void operator++() {}22  const T& operator*() {23    static T* TT = new T();24    return *TT;25  }26  bool operator!=(const Iterator &) { return false; }27  typedef const T& const_reference;28};29template <typename T>30struct View {31  View() = default;32  T begin() { return T(); }33  T begin() const { return T(); }34  T end() { return T(); }35  T end() const { return T(); }36  typedef typename T::const_reference const_reference;37};38 39struct ConstructorConvertible {40};41 42struct S {43  S();44  S(const S &);45  S(const ConstructorConvertible&) {}46  ~S();47  S &operator=(const S &);48};49 50struct Point {51  ~Point() {}52  int x, y;53};54 55struct Convertible {56  operator S() const {57    return S();58  }59};60 61void negativeConstReference() {62  for (const S &S1 : View<Iterator<S>>()) {63  }64}65 66void negativeUserDefinedConversion() {67  Convertible C[0];68  for (const S S1 : C) {69  }70}71 72void negativeImplicitConstructorConversion() {73  ConstructorConvertible C[0];74  for (const S S1 : C) {75  }76}77 78template <typename T>79void uninstantiated() {80  for (const S S1 : View<Iterator<S>>()) {}81  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: the loop variable's type is not a reference type; this creates a copy in each iteration; consider making this a reference [performance-for-range-copy]82  // CHECK-FIXES: for (const S& S1 : View<Iterator<S>>()) {}83 84  // Don't warn on dependent types.85  for (const T t1 : View<Iterator<T>>()) {86  }87}88 89template <typename T>90void instantiated() {91  for (const S S2 : View<Iterator<S>>()) {}92  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: the loop variable's type is {{.*}}93  // CHECK-FIXES: for (const S& S2 : View<Iterator<S>>()) {}94 95  for (const auto [X, Y] : View<Iterator<Point>>()) {}96  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: the loop variable's type is97  // CHECK-FIXES: for (const auto& [X, Y] : View<Iterator<Point>>()) {}98 99  for (const T T2 : View<Iterator<T>>()) {}100  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: the loop variable's type is {{.*}}101  // CHECK-FIXES: for (const T& T2 : View<Iterator<T>>()) {}102}103 104template <typename T>105void instantiatedNegativeTypedefConstReference() {106  for (typename T::const_reference T2 : T()) {107    S S1 = T2;108  }109}110 111void f() {112  instantiated<int>();113  instantiated<S>();114  instantiatedNegativeTypedefConstReference<View<Iterator<S>>>();115}116 117struct Mutable {118  Mutable() {}119  Mutable(const Mutable &) = default;120  Mutable(Mutable&&) = default;121  Mutable(const Mutable &, const Mutable &) {}122  void setBool(bool B) {}123  bool constMethod() const {124    return true;125  }126  Mutable& operator[](int I) {127    return *this;128  }129  bool operator==(const Mutable &Other) const {130    return true;131  }132  ~Mutable() {}133};134 135Mutable& operator<<(Mutable &Out, bool B) {136  Out.setBool(B);137  return Out;138}139 140bool operator!=(const Mutable& M1, const Mutable& M2) {141  return false;142}143 144void use(const Mutable &M);145void use(int I);146void useTwice(const Mutable &M1, const Mutable &M2);147void useByValue(Mutable M);148void useByConstValue(const Mutable M);149void mutate(Mutable *M);150void mutate(Mutable &M);151void mutate(int &);152void onceConstOnceMutated(const Mutable &M1, Mutable &M2);153 154void negativeVariableIsMutated() {155  for (auto M : View<Iterator<Mutable>>()) {156    mutate(M);157  }158  for (auto M : View<Iterator<Mutable>>()) {159    mutate(&M);160  }161  for (auto M : View<Iterator<Mutable>>()) {162    M.setBool(true);163  }164}165 166void negativeOnceConstOnceMutated() {167  for (auto M : View<Iterator<Mutable>>()) {168    onceConstOnceMutated(M, M);169  }170}171 172void negativeVarIsMoved() {173  for (auto M : View<Iterator<Mutable>>()) {174    auto Moved = std::move(M);175  }176}177 178void negativeNonConstOperatorIsInvoked() {179  for (auto NonConstOperatorInvokee : View<Iterator<Mutable>>()) {180    auto& N = NonConstOperatorInvokee[0];181  }182}183 184void negativeNonConstNonMemberOperatorInvoked() {185  for (auto NonConstOperatorInvokee : View<Iterator<Mutable>>()) {186    NonConstOperatorInvokee << true;187  }188}189 190void negativeConstCheapToCopy() {191  for (const int I : View<Iterator<int>>()) {192  }193}194 195void negativeConstCheapToCopyTypedef() {196  typedef const int ConstInt;197  for (ConstInt C  : View<Iterator<ConstInt>>()) {198  }199}200 201void negativeCheapToCopy() {202  for (int I : View<Iterator<int>>()) {203    use(I);204  }205}206 207void negativeCheapToCopyTypedef() {208  typedef int Int;209  for (Int I : View<Iterator<Int>>()) {210    use(I);211  }212}213 214void positiveOnlyConstMethodInvoked() {215  for (auto M : View<Iterator<Mutable>>()) {216    // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]217    // CHECK-FIXES: for (const auto& M : View<Iterator<Mutable>>()) {218    M.constMethod();219  }220}221 222void positiveOnlyUsedAsConstArguments() {223  for (auto UsedAsConst : View<Iterator<Mutable>>()) {224    // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]225    // CHECK-FIXES: for (const auto& UsedAsConst : View<Iterator<Mutable>>()) {226    use(UsedAsConst);227    useTwice(UsedAsConst, UsedAsConst);228    useByValue(UsedAsConst);229    useByConstValue(UsedAsConst);230  }231}232 233void positiveOnlyAccessedFieldAsConst() {234  for (auto UsedAsConst : View<Iterator<Point>>()) {235    // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]236    // CHECK-FIXES: for (const auto& UsedAsConst : View<Iterator<Point>>()) {237    use(UsedAsConst.x);238    use(UsedAsConst.y);239  }240}241 242void positiveOnlyUsedAsConstBinding() {243  for (auto [X, Y] : View<Iterator<Point>>()) {244    // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but245    // CHECK-FIXES: for (const auto& [X, Y] : View<Iterator<Point>>()) {246    use(X);247    use(Y);248  }249}250 251void negativeMutatedBinding() {252  for (auto [X, Y] : View<Iterator<Point>>()) {253    use(X);254    mutate(Y);255  }256}257 258void positiveOnlyUsedInCopyConstructor() {259  for (auto A : View<Iterator<Mutable>>()) {260    // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]261    // CHECK-FIXES: for (const auto& A : View<Iterator<Mutable>>()) {262    Mutable Copy = A;263    Mutable Copy2(A);264  }265}266 267void positiveTwoConstConstructorArgs() {268  for (auto A : View<Iterator<Mutable>>()) {269    // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]270    // CHECK-FIXES: for (const auto& A : View<Iterator<Mutable>>()) {271    Mutable Copy(A, A);272  }273}274 275void PositiveConstMemberOperatorInvoked() {276  for (auto ConstOperatorInvokee : View<Iterator<Mutable>>()) {277    // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]278    // CHECK-FIXES: for (const auto& ConstOperatorInvokee : View<Iterator<Mutable>>()) {279    bool result = ConstOperatorInvokee == Mutable();280  }281}282 283void PositiveConstNonMemberOperatorInvoked() {284  for (auto ConstOperatorInvokee : View<Iterator<Mutable>>()) {285    // CHECK-MESSAGES: [[@LINE-1]]:13: warning: loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy]286    // CHECK-FIXES: for (const auto& ConstOperatorInvokee : View<Iterator<Mutable>>()) {287    bool result = ConstOperatorInvokee != Mutable();288  }289}290 291void IgnoreLoopVariableNotUsedInLoopBody() {292  for (auto _ : View<Iterator<S>>()) {293  }294}295 296template <typename T>297struct ValueReturningIterator {298  void operator++() {}299  T operator*() { return T(); }300  bool operator!=(const ValueReturningIterator &) { return false; }301  typedef const T &const_reference;302};303 304void negativeValueIterator() {305  // Check does not trigger for iterators that return elements by value.306  for (const S SS : View<ValueReturningIterator<S>>()) {307  }308}309 310View<Iterator<S>> createView(S) { return View<Iterator<S>>(); }311 312void positiveValueIteratorUsedElseWhere() {313  for (const S SS : createView(*ValueReturningIterator<S>())) {314    // CHECK-MESSAGES: [[@LINE-1]]:16: warning: the loop variable's type is not a reference type; this creates a copy in each iteration; consider making this a reference [performance-for-range-copy]315    // CHECK-FIXES: for (const S& SS : createView(*ValueReturningIterator<S>())) {316  }317}318 319void positiveConstMemberExpr() {320  struct Struct {321    Mutable Member;322  };323  for (Struct SS : View<Iterator<Struct>>()) {324    // CHECK-MESSAGES: [[@LINE-1]]:15: warning: loop variable is copied325    // CHECK-FIXES: for (const Struct& SS : View<Iterator<Struct>>()) {326    auto MemberCopy = SS.Member;327    const auto &ConstRef = SS.Member;328    bool b = SS.Member.constMethod();329    use(SS.Member);330    useByConstValue(SS.Member);331    useByValue(SS.Member);332  }333}334 335void negativeNonConstMemberExpr() {336  struct Struct {337    Mutable Member;338  };339  for (Struct SS : View<Iterator<Struct>>()) {340    SS.Member.setBool(true);341  }342  for (Struct SS : View<Iterator<Struct>>()) {343    SS.Member[1];344  }345  for (Struct SS : View<Iterator<Struct>>()) {346    mutate(SS.Member);347  }348  for (Struct SS : View<Iterator<Struct>>()) {349    mutate(&SS.Member);350  }351}352 353