1 // RUN: %check_clang_tidy %s performance-for-range-copy %t -- \
2 // RUN:     -config="{CheckOptions: [{key: performance-for-range-copy.AllowedTypes, value: '[Pp]ointer$;[Pp]tr$;[Rr]ef(erence)?$'}]}" \
3 // RUN:     -- -fno-delayed-template-parsing
4 
5 template <typename T>
6 struct Iterator {
operator ++Iterator7   void operator++() {}
operator *Iterator8   const T& operator*() {
9     static T* TT = new T();
10     return *TT;
11   }
operator !=Iterator12   bool operator!=(const Iterator &) { return false; }
13   typedef const T& const_reference;
14 };
15 template <typename T>
16 struct View {
beginView17   T begin() { return T(); }
beginView18   T begin() const { return T(); }
endView19   T end() { return T(); }
endView20   T end() const { return T(); }
21   typedef typename T::const_reference const_reference;
22 };
23 
24 struct SmartPointer {
25   ~SmartPointer();
26 };
27 
28 struct smart_pointer {
29   ~smart_pointer();
30 };
31 
32 struct SmartPtr {
33   ~SmartPtr();
34 };
35 
36 struct smart_ptr {
37   ~smart_ptr();
38 };
39 
40 struct SmartReference {
41   ~SmartReference();
42 };
43 
44 struct smart_reference {
45   ~smart_reference();
46 };
47 
48 struct SmartRef {
49   ~SmartRef();
50 };
51 
52 struct smart_ref {
53   ~smart_ref();
54 };
55 
56 struct OtherType {
57   ~OtherType();
58 };
59 
60 template <typename T> struct SomeComplexTemplate {
61   ~SomeComplexTemplate();
62 };
63 
64 typedef SomeComplexTemplate<int> NotTooComplexRef;
65 
negativeSmartPointer()66 void negativeSmartPointer() {
67   for (auto P : View<Iterator<SmartPointer>>()) {
68     auto P2 = P;
69   }
70 }
71 
negative_smart_pointer()72 void negative_smart_pointer() {
73   for (auto p : View<Iterator<smart_pointer>>()) {
74     auto p2 = p;
75   }
76 }
77 
negativeSmartPtr()78 void negativeSmartPtr() {
79   for (auto P : View<Iterator<SmartPtr>>()) {
80     auto P2 = P;
81   }
82 }
83 
negative_smart_ptr()84 void negative_smart_ptr() {
85   for (auto p : View<Iterator<smart_ptr>>()) {
86     auto p2 = p;
87   }
88 }
89 
negativeSmartReference()90 void negativeSmartReference() {
91   for (auto R : View<Iterator<SmartReference>>()) {
92     auto R2 = R;
93   }
94 }
95 
negative_smart_reference()96 void negative_smart_reference() {
97   for (auto r : View<Iterator<smart_reference>>()) {
98     auto r2 = r;
99   }
100 }
101 
negativeSmartRef()102 void negativeSmartRef() {
103   for (auto R : View<Iterator<SmartRef>>()) {
104     auto R2 = R;
105   }
106 }
107 
negative_smart_ref()108 void negative_smart_ref() {
109   for (auto r : View<Iterator<smart_ref>>()) {
110     auto r2 = r;
111   }
112 }
113 
positiveOtherType()114 void positiveOtherType() {
115   for (auto O : View<Iterator<OtherType>>()) {
116   // 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]
117   // CHECK-FIXES: for (const auto& O : View<Iterator<OtherType>>()) {
118     auto O2 = O;
119   }
120 }
121 
negativeNotTooComplexRef()122 void negativeNotTooComplexRef() {
123   for (NotTooComplexRef R : View<Iterator<NotTooComplexRef>>()) {
124     auto R2 = R;
125   }
126 }
127