| 1 | // RUN: %check_clang_tidy %s performance-for-range-copy %t -- \ |
| 2 | // RUN: -config="{CheckOptions: {performance-for-range-copy.WarnOnAllAutoCopies: true}}" |
| 3 | |
| 4 | template <typename T> |
| 5 | struct Iterator { |
| 6 | void operator++() {} |
| 7 | const T& operator*() { |
| 8 | static T* TT = new T(); |
| 9 | return *TT; |
| 10 | } |
| 11 | bool operator!=(const Iterator &) { return false; } |
| 12 | }; |
| 13 | template <typename T> |
| 14 | struct View { |
| 15 | T begin() { return T(); } |
| 16 | T begin() const { return T(); } |
| 17 | T end() { return T(); } |
| 18 | T end() const { return T(); } |
| 19 | }; |
| 20 | |
| 21 | struct S { |
| 22 | S(); |
| 23 | S(const S &); |
| 24 | ~S(); |
| 25 | S &operator=(const S &); |
| 26 | }; |
| 27 | |
| 28 | void NegativeLoopVariableNotAuto() { |
| 29 | for (S S1 : View<Iterator<S>>()) { |
| 30 | S* S2 = &S1; |
| 31 | } |
| 32 | } |
| 33 | |
| 34 | void PositiveTriggeredForAutoLoopVariable() { |
| 35 | for (auto S1 : View<Iterator<S>>()) { |
| 36 | // CHECK-MESSAGES: [[@LINE-1]]:13: 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] |
| 37 | // CHECK-FIXES: for (const auto& S1 : View<Iterator<S>>()) { |
| 38 | S* S2 = &S1; |
| 39 | } |
| 40 | } |
| 41 | |