1 | // RUN: %check_clang_tidy %s readability-redundant-smartptr-get %t |
2 | |
3 | #define NULL __null |
4 | |
5 | namespace std { |
6 | |
7 | // MSVC headers define operator templates instead of plain operators. |
8 | |
9 | template <typename T> |
10 | struct unique_ptr { |
11 | template <typename T2 = T> |
12 | T2& operator*() const; |
13 | template <typename T2 = T> |
14 | T2* operator->() const; |
15 | T* get() const; |
16 | explicit operator bool() const noexcept; |
17 | }; |
18 | |
19 | template <typename T> |
20 | struct unique_ptr<T[]> { |
21 | template <typename T2 = T> |
22 | T2* operator[](unsigned) const; |
23 | T* get() const; |
24 | explicit operator bool() const noexcept; |
25 | }; |
26 | |
27 | template <typename T> |
28 | struct shared_ptr { |
29 | template <typename T2 = T> |
30 | T2& operator*() const; |
31 | template <typename T2 = T> |
32 | T2* operator->() const; |
33 | T* get() const; |
34 | explicit operator bool() const noexcept; |
35 | }; |
36 | |
37 | template <typename T> |
38 | struct shared_ptr<T[]> { |
39 | template <typename T2 = T> |
40 | T2* operator[](unsigned) const; |
41 | T* get() const; |
42 | explicit operator bool() const noexcept; |
43 | }; |
44 | |
45 | } // namespace std |
46 | |
47 | struct Bar { |
48 | void Do(); |
49 | void ConstDo() const; |
50 | }; |
51 | |
52 | void Positive() { |
53 | std::unique_ptr<Bar>* up; |
54 | (*up->get()).Do(); |
55 | // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: redundant get() call |
56 | // CHECK-MESSAGES: (*up->get()).Do(); |
57 | // CHECK-FIXES: (**up).Do(); |
58 | |
59 | std::unique_ptr<int> uu; |
60 | std::shared_ptr<double> *ss; |
61 | bool bb = uu.get() == nullptr; |
62 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call |
63 | // CHECK-MESSAGES: uu.get() == nullptr; |
64 | // CHECK-FIXES: bool bb = uu == nullptr; |
65 | |
66 | if (up->get()); |
67 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call |
68 | // CHECK-MESSAGES: if (up->get()); |
69 | // CHECK-FIXES: if (*up); |
70 | if ((uu.get())); |
71 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call |
72 | // CHECK-MESSAGES: if ((uu.get())); |
73 | // CHECK-FIXES: if ((uu)); |
74 | bb = !ss->get(); |
75 | // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant get() call |
76 | // CHECK-MESSAGES: bb = !ss->get(); |
77 | // CHECK-FIXES: bb = !*ss; |
78 | |
79 | bb = nullptr != ss->get(); |
80 | // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: redundant get() call |
81 | // CHECK-MESSAGES: nullptr != ss->get(); |
82 | // CHECK-FIXES: bb = nullptr != *ss; |
83 | |
84 | bb = std::unique_ptr<int>().get() == NULL; |
85 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call |
86 | // CHECK-MESSAGES: bb = std::unique_ptr<int>().get() == NULL; |
87 | // CHECK-FIXES: bb = std::unique_ptr<int>() == NULL; |
88 | bb = ss->get() == NULL; |
89 | // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: redundant get() call |
90 | // CHECK-MESSAGES: bb = ss->get() == NULL; |
91 | // CHECK-FIXES: bb = *ss == NULL; |
92 | |
93 | std::unique_ptr<int> x, y; |
94 | if (x.get() == nullptr); |
95 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call |
96 | // CHECK-MESSAGES: if (x.get() == nullptr); |
97 | // CHECK-FIXES: if (x == nullptr); |
98 | if (nullptr == y.get()); |
99 | // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: redundant get() call |
100 | // CHECK-MESSAGES: if (nullptr == y.get()); |
101 | // CHECK-FIXES: if (nullptr == y); |
102 | if (x.get() == NULL); |
103 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call |
104 | // CHECK-MESSAGES: if (x.get() == NULL); |
105 | // CHECK-FIXES: if (x == NULL); |
106 | if (NULL == x.get()); |
107 | // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: redundant get() call |
108 | // CHECK-MESSAGES: if (NULL == x.get()); |
109 | // CHECK-FIXES: if (NULL == x); |
110 | } |
111 | |
112 | void test_smart_ptr_to_array() { |
113 | std::unique_ptr<int[]> i; |
114 | // The array specialization does not have operator*(), so make sure |
115 | // we do not incorrectly suggest sizeof(*i) here. |
116 | // FIXME: alternatively, we could suggest sizeof(i[0]) |
117 | auto sz = sizeof(*i.get()); |
118 | |
119 | std::shared_ptr<Bar[]> s; |
120 | // The array specialization does not have operator->() either |
121 | s.get()->Do(); |
122 | |
123 | bool b1 = !s.get(); |
124 | // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: redundant get() call |
125 | // CHECK-FIXES: bool b1 = !s; |
126 | |
127 | if (s.get()) {} |
128 | // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant get() call |
129 | // CHECK-FIXES: if (s) {} |
130 | |
131 | int x = s.get() ? 1 : 2; |
132 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant get() call |
133 | // CHECK-FIXES: int x = s ? 1 : 2; |
134 | |
135 | bool b2 = s.get() == nullptr; |
136 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant get() call |
137 | // CHECK-FIXES: bool b2 = s == nullptr; |
138 | } |
139 | |