1// RUN: %check_clang_tidy %s readability-redundant-smartptr-get %t
2
3#define NULL __null
4
5namespace std {
6
7template <typename T>
8struct unique_ptr {
9 T& operator*() const;
10 T* operator->() const;
11 T* get() const;
12 explicit operator bool() const noexcept;
13};
14
15template <typename T>
16struct unique_ptr<T[]> {
17 T& operator[](unsigned) const;
18 T* get() const;
19 explicit operator bool() const noexcept;
20};
21
22template <typename T>
23struct shared_ptr {
24 T& operator*() const;
25 T* operator->() const;
26 T* get() const;
27 explicit operator bool() const noexcept;
28};
29
30template <typename T>
31struct shared_ptr<T[]> {
32 T& operator[](unsigned) const;
33 T* get() const;
34 explicit operator bool() const noexcept;
35};
36
37template <typename T>
38struct vector {
39 vector();
40 bool operator==(const vector<T>& other) const;
41 bool operator!=(const vector<T>& other) const;
42 unsigned long size() const;
43 bool empty() const;
44
45 using iterator = T*;
46
47 iterator begin();
48 iterator end();
49
50 T* data;
51 unsigned long sz;
52};
53
54} // namespace std
55
56struct Bar {
57 void Do();
58 void ConstDo() const;
59};
60struct BarPtr {
61 Bar* operator->();
62 Bar& operator*();
63 Bar* get();
64 explicit operator bool() const;
65};
66struct int_ptr {
67 int* get();
68 int* operator->();
69 int& operator*();
70};
71
72struct Fail1 {
73 Bar* get();
74};
75struct Fail2 {
76 Bar* get();
77 int* operator->();
78 int& operator*();
79};
80
81struct PointerWithOverloadedGet {
82 int* get();
83 template <typename T>
84 T* get();
85 int* operator->();
86 int& operator*();
87};
88
89void Positive() {
90 BarPtr u;
91 // CHECK-FIXES: BarPtr u;
92 BarPtr().get()->Do();
93 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant get() call on smart pointer [readability-redundant-smartptr-get]
94 // CHECK-MESSAGES: BarPtr().get()->Do();
95 // CHECK-FIXES: BarPtr()->Do();
96
97 u.get()->ConstDo();
98 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant get() call
99 // CHECK-MESSAGES: u.get()->ConstDo();
100 // CHECK-FIXES: u->ConstDo();
101
102 Bar& b = *BarPtr().get();
103 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call
104 // CHECK-MESSAGES: Bar& b = *BarPtr().get();
105 // CHECK-FIXES: Bar& b = *BarPtr();
106
107 Bar& b2 = *std::unique_ptr<Bar>().get();
108 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant get() call
109 // CHECK-MESSAGES: Bar& b2 = *std::unique_ptr<Bar>().get();
110 // CHECK-FIXES: Bar& b2 = *std::unique_ptr<Bar>();
111
112 (*BarPtr().get()).ConstDo();
113 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call
114 // CHECK-MESSAGES: (*BarPtr().get()).ConstDo();
115 // CHECK-FIXES: (*BarPtr()).ConstDo();
116
117 (*std::unique_ptr<Bar>().get()).ConstDo();
118 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call
119 // CHECK-MESSAGES: (*std::unique_ptr<Bar>().get()).ConstDo();
120 // CHECK-FIXES: (*std::unique_ptr<Bar>()).ConstDo();
121
122 std::unique_ptr<Bar>* up;
123 (*up->get()).Do();
124 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call
125 // CHECK-MESSAGES: (*up->get()).Do();
126 // CHECK-FIXES: (**up).Do();
127
128 int_ptr ip;
129 int i = *ip.get();
130 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant get() call
131 // CHECK-MESSAGES: int i = *ip.get();
132 // CHECK-FIXES: int i = *ip;
133
134 auto ip2 = ip;
135 i = *ip2.get();
136 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
137 // CHECK-MESSAGES: i = *ip2.get();
138 // CHECK-FIXES: i = *ip2;
139
140 std::unique_ptr<int> uu;
141 std::shared_ptr<double> *ss;
142 bool bb = uu.get() == nullptr;
143 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call
144 // CHECK-MESSAGES: uu.get() == nullptr;
145 // CHECK-FIXES: bool bb = uu == nullptr;
146
147 if (up->get());
148 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
149 // CHECK-MESSAGES: if (up->get());
150 // CHECK-FIXES: if (*up);
151 if ((uu.get()));
152 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
153 // CHECK-MESSAGES: if ((uu.get()));
154 // CHECK-FIXES: if ((uu));
155 bb = !ss->get();
156 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant get() call
157 // CHECK-MESSAGES: bb = !ss->get();
158 // CHECK-FIXES: bb = !*ss;
159 bb = u.get() ? true : false;
160 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
161 // CHECK-MESSAGES: bb = u.get() ? true : false;
162 // CHECK-FIXES: bb = u ? true : false;
163
164 bb = nullptr != ss->get();
165 // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant get() call
166 // CHECK-MESSAGES: nullptr != ss->get();
167 // CHECK-FIXES: bb = nullptr != *ss;
168
169 i = *PointerWithOverloadedGet().get();
170 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
171 // CHECK-MESSAGES: i = *PointerWithOverloadedGet().get();
172 // CHECK-FIXES: i = *PointerWithOverloadedGet();
173
174 bb = std::unique_ptr<int>().get() == NULL;
175 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
176 // CHECK-MESSAGES: bb = std::unique_ptr<int>().get() == NULL;
177 // CHECK-FIXES: bb = std::unique_ptr<int>() == NULL;
178 bb = ss->get() == NULL;
179 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
180 // CHECK-MESSAGES: bb = ss->get() == NULL;
181 // CHECK-FIXES: bb = *ss == NULL;
182
183 std::unique_ptr<int> x, y;
184 if (x.get() == nullptr);
185 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
186 // CHECK-MESSAGES: if (x.get() == nullptr);
187 // CHECK-FIXES: if (x == nullptr);
188 if (nullptr == y.get());
189 // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: redundant get() call
190 // CHECK-MESSAGES: if (nullptr == y.get());
191 // CHECK-FIXES: if (nullptr == y);
192 if (x.get() == NULL);
193 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
194 // CHECK-MESSAGES: if (x.get() == NULL);
195 // CHECK-FIXES: if (x == NULL);
196 if (NULL == x.get());
197 // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant get() call
198 // CHECK-MESSAGES: if (NULL == x.get());
199 // CHECK-FIXES: if (NULL == x);
200}
201
202template <typename T>
203void testTemplate() {
204 T().get()->Do();
205}
206
207template <typename T>
208void testTemplate2() {
209 std::unique_ptr<T> up;
210 up.get()->Do();
211 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant get() call
212 // CHECK-FIXES: up->Do();
213}
214
215void instantiate() {
216 testTemplate<BarPtr>();
217 testTemplate<std::unique_ptr<Bar>>();
218 testTemplate<Fail2>();
219
220 testTemplate2<Bar>();
221}
222
223struct S {
224
225 void foo() {
226 m_up.get()->Do();
227 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call
228 // CHECK-FIXES: m_up->Do();
229 m_bp.get()->Do();
230 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call
231 // CHECK-FIXES: m_bp->Do();
232 }
233
234 std::unique_ptr<Bar> m_up;
235 BarPtr m_bp;
236};
237
238#define MACRO(p) p.get()
239
240void Negative() {
241 struct NegPtr {
242 int* get();
243 int* operator->() {
244 return &*this->get();
245 }
246 int& operator*() {
247 return *get();
248 }
249 };
250
251 long l = *PointerWithOverloadedGet().get<long>();
252
253 std::unique_ptr<Bar>* u;
254 u->get()->Do();
255
256 Fail1().get()->Do();
257 Fail2().get()->Do();
258 const Bar& b = *Fail1().get();
259 (*Fail2().get()).Do();
260
261 int_ptr ip;
262 bool bb = ip.get() == nullptr;
263 bb = !ip.get();
264 bb = ip.get() ? true : false;
265 std::unique_ptr<int> x;
266 if (MACRO(x) == nullptr)
267 ;
268}
269
270void test_redundant_get() {
271 std::vector<std::shared_ptr<int>> v;
272 auto f = [](int) {};
273 for (auto i = v.begin(); i != v.end(); ++i) {
274 f(*i->get());
275 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
276 // CHECK-FIXES: f(**i);
277 }
278}
279
280struct Inner {
281 int a;
282 int *getValue() { return &a; }
283};
284
285struct Example {
286 Inner inner;
287 Inner* get() { return &inner; }
288 int *getValue() { return inner.getValue(); }
289};
290
291void test_redundant_get_with_member() {
292 std::vector<std::shared_ptr<Example>> v;
293 auto f = [](int) {};
294 for (auto i = v.begin(); i != v.end(); ++i) {
295 f(*(*i).get()->get()->getValue());
296 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call
297 // CHECK-FIXES: f(**i->get()->getValue());
298 }
299}
300
301void test_smart_ptr_to_array() {
302 std::unique_ptr<int[]> i;
303 // The array specialization does not have operator*(), so make sure
304 // we do not incorrectly suggest sizeof(*i) here.
305 // FIXME: alternatively, we could suggest sizeof(i[0])
306 auto sz = sizeof(*i.get());
307
308 std::shared_ptr<Inner[]> s;
309 // The array specialization does not have operator->() either
310 s.get()->getValue();
311
312 bool b1 = !s.get();
313 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant get() call
314 // CHECK-FIXES: bool b1 = !s;
315
316 if (s.get()) {}
317 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call
318 // CHECK-FIXES: if (s) {}
319
320 int x = s.get() ? 1 : 2;
321 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant get() call
322 // CHECK-FIXES: int x = s ? 1 : 2;
323
324 bool b2 = s.get() == nullptr;
325 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call
326 // CHECK-FIXES: bool b2 = s == nullptr;
327}
328

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang-tools-extra/test/clang-tidy/checkers/readability/redundant-smartptr-get.cpp