1 // RUN: %check_clang_tidy %s readability-redundant-smartptr-get %t 2 3 #define NULL __null 4 5 namespace std { 6 7 template <typename T> 8 struct unique_ptr { 9 T& operator*() const; 10 T* operator->() const; 11 T* get() const; 12 explicit operator bool() const noexcept; 13 }; 14 15 template <typename T> 16 struct shared_ptr { 17 T& operator*() const; 18 T* operator->() const; 19 T* get() const; 20 explicit operator bool() const noexcept; 21 }; 22 23 } // namespace std 24 25 struct Bar { 26 void Do(); 27 void ConstDo() const; 28 }; 29 struct BarPtr { 30 Bar* operator->(); 31 Bar& operator*(); 32 Bar* get(); 33 explicit operator bool() const; 34 }; 35 struct int_ptr { 36 int* get(); 37 int* operator->(); 38 int& operator*(); 39 }; 40 41 struct Fail1 { 42 Bar* get(); 43 }; 44 struct Fail2 { 45 Bar* get(); 46 int* operator->(); 47 int& operator*(); 48 }; 49 50 struct PointerWithOverloadedGet { 51 int* get(); 52 template <typename T> 53 T* get(); 54 int* operator->(); 55 int& operator*(); 56 }; 57 Positive()58void Positive() { 59 BarPtr u; 60 // CHECK-FIXES: BarPtr u; 61 BarPtr().get()->Do(); 62 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant get() call on smart pointer [readability-redundant-smartptr-get] 63 // CHECK-MESSAGES: BarPtr().get()->Do(); 64 // CHECK-FIXES: BarPtr()->Do(); 65 66 u.get()->ConstDo(); 67 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant get() call 68 // CHECK-MESSAGES: u.get()->ConstDo(); 69 // CHECK-FIXES: u->ConstDo(); 70 71 Bar& b = *BarPtr().get(); 72 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call 73 // CHECK-MESSAGES: Bar& b = *BarPtr().get(); 74 // CHECK-FIXES: Bar& b = *BarPtr(); 75 76 Bar& b2 = *std::unique_ptr<Bar>().get(); 77 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant get() call 78 // CHECK-MESSAGES: Bar& b2 = *std::unique_ptr<Bar>().get(); 79 // CHECK-FIXES: Bar& b2 = *std::unique_ptr<Bar>(); 80 81 (*BarPtr().get()).ConstDo(); 82 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call 83 // CHECK-MESSAGES: (*BarPtr().get()).ConstDo(); 84 // CHECK-FIXES: (*BarPtr()).ConstDo(); 85 86 (*std::unique_ptr<Bar>().get()).ConstDo(); 87 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call 88 // CHECK-MESSAGES: (*std::unique_ptr<Bar>().get()).ConstDo(); 89 // CHECK-FIXES: (*std::unique_ptr<Bar>()).ConstDo(); 90 91 std::unique_ptr<Bar>* up; 92 (*up->get()).Do(); 93 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call 94 // CHECK-MESSAGES: (*up->get()).Do(); 95 // CHECK-FIXES: (**up).Do(); 96 97 int_ptr ip; 98 int i = *ip.get(); 99 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant get() call 100 // CHECK-MESSAGES: int i = *ip.get(); 101 // CHECK-FIXES: int i = *ip; 102 103 auto ip2 = ip; 104 i = *ip2.get(); 105 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call 106 // CHECK-MESSAGES: i = *ip2.get(); 107 // CHECK-FIXES: i = *ip2; 108 109 std::unique_ptr<int> uu; 110 std::shared_ptr<double> *ss; 111 bool bb = uu.get() == nullptr; 112 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call 113 // CHECK-MESSAGES: uu.get() == nullptr; 114 // CHECK-FIXES: bool bb = uu == nullptr; 115 116 if (up->get()); 117 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call 118 // CHECK-MESSAGES: if (up->get()); 119 // CHECK-FIXES: if (*up); 120 if ((uu.get())); 121 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call 122 // CHECK-MESSAGES: if ((uu.get())); 123 // CHECK-FIXES: if ((uu)); 124 bb = !ss->get(); 125 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant get() call 126 // CHECK-MESSAGES: bb = !ss->get(); 127 // CHECK-FIXES: bb = !*ss; 128 bb = u.get() ? true : false; 129 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call 130 // CHECK-MESSAGES: bb = u.get() ? true : false; 131 // CHECK-FIXES: bb = u ? true : false; 132 133 bb = nullptr != ss->get(); 134 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant get() call 135 // CHECK-MESSAGES: nullptr != ss->get(); 136 // CHECK-FIXES: bb = nullptr != *ss; 137 138 i = *PointerWithOverloadedGet().get(); 139 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call 140 // CHECK-MESSAGES: i = *PointerWithOverloadedGet().get(); 141 // CHECK-FIXES: i = *PointerWithOverloadedGet(); 142 143 bb = std::unique_ptr<int>().get() == NULL; 144 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call 145 // CHECK-MESSAGES: bb = std::unique_ptr<int>().get() == NULL; 146 // CHECK-FIXES: bb = std::unique_ptr<int>() == NULL; 147 bb = ss->get() == NULL; 148 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call 149 // CHECK-MESSAGES: bb = ss->get() == NULL; 150 // CHECK-FIXES: bb = *ss == NULL; 151 152 std::unique_ptr<int> x, y; 153 if (x.get() == nullptr); 154 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call 155 // CHECK-MESSAGES: if (x.get() == nullptr); 156 // CHECK-FIXES: if (x == nullptr); 157 if (nullptr == y.get()); 158 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: redundant get() call 159 // CHECK-MESSAGES: if (nullptr == y.get()); 160 // CHECK-FIXES: if (nullptr == y); 161 if (x.get() == NULL); 162 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call 163 // CHECK-MESSAGES: if (x.get() == NULL); 164 // CHECK-FIXES: if (x == NULL); 165 if (NULL == x.get()); 166 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant get() call 167 // CHECK-MESSAGES: if (NULL == x.get()); 168 // CHECK-FIXES: if (NULL == x); 169 } 170 171 template <typename T> testTemplate()172void testTemplate() { 173 T().get()->Do(); 174 } 175 176 template <typename T> testTemplate2()177void testTemplate2() { 178 std::unique_ptr<T> up; 179 up.get()->Do(); 180 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant get() call 181 // CHECK-FIXES: up->Do(); 182 } 183 instantiate()184void instantiate() { 185 testTemplate<BarPtr>(); 186 testTemplate<std::unique_ptr<Bar>>(); 187 testTemplate<Fail2>(); 188 189 testTemplate2<Bar>(); 190 } 191 192 struct S { 193 fooS194 void foo() { 195 m_up.get()->Do(); 196 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call 197 // CHECK-FIXES: m_up->Do(); 198 m_bp.get()->Do(); 199 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call 200 // CHECK-FIXES: m_bp->Do(); 201 } 202 203 std::unique_ptr<Bar> m_up; 204 BarPtr m_bp; 205 }; 206 207 #define MACRO(p) p.get() 208 Negative()209void Negative() { 210 struct NegPtr { 211 int* get(); 212 int* operator->() { 213 return &*this->get(); 214 } 215 int& operator*() { 216 return *get(); 217 } 218 }; 219 220 long l = *PointerWithOverloadedGet().get<long>(); 221 222 std::unique_ptr<Bar>* u; 223 u->get()->Do(); 224 225 Fail1().get()->Do(); 226 Fail2().get()->Do(); 227 const Bar& b = *Fail1().get(); 228 (*Fail2().get()).Do(); 229 230 int_ptr ip; 231 bool bb = ip.get() == nullptr; 232 bb = !ip.get(); 233 bb = ip.get() ? true : false; 234 std::unique_ptr<int> x; 235 if (MACRO(x) == nullptr) 236 ; 237 } 238