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()66void negativeSmartPointer() { 67 for (auto P : View<Iterator<SmartPointer>>()) { 68 auto P2 = P; 69 } 70 } 71 negative_smart_pointer()72void negative_smart_pointer() { 73 for (auto p : View<Iterator<smart_pointer>>()) { 74 auto p2 = p; 75 } 76 } 77 negativeSmartPtr()78void negativeSmartPtr() { 79 for (auto P : View<Iterator<SmartPtr>>()) { 80 auto P2 = P; 81 } 82 } 83 negative_smart_ptr()84void negative_smart_ptr() { 85 for (auto p : View<Iterator<smart_ptr>>()) { 86 auto p2 = p; 87 } 88 } 89 negativeSmartReference()90void negativeSmartReference() { 91 for (auto R : View<Iterator<SmartReference>>()) { 92 auto R2 = R; 93 } 94 } 95 negative_smart_reference()96void negative_smart_reference() { 97 for (auto r : View<Iterator<smart_reference>>()) { 98 auto r2 = r; 99 } 100 } 101 negativeSmartRef()102void negativeSmartRef() { 103 for (auto R : View<Iterator<SmartRef>>()) { 104 auto R2 = R; 105 } 106 } 107 negative_smart_ref()108void negative_smart_ref() { 109 for (auto r : View<Iterator<smart_ref>>()) { 110 auto r2 = r; 111 } 112 } 113 positiveOtherType()114void 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()122void negativeNotTooComplexRef() { 123 for (NotTooComplexRef R : View<Iterator<NotTooComplexRef>>()) { 124 auto R2 = R; 125 } 126 } 127