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 | |
58 | void 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> |
172 | void testTemplate() { |
173 | T().get()->Do(); |
174 | } |
175 | |
176 | template <typename T> |
177 | void 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 | |
184 | void instantiate() { |
185 | testTemplate<BarPtr>(); |
186 | testTemplate<std::unique_ptr<Bar>>(); |
187 | testTemplate<Fail2>(); |
188 | |
189 | testTemplate2<Bar>(); |
190 | } |
191 | |
192 | struct S { |
193 | |
194 | 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 | |
209 | void 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 | |