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 | |