1 | // RUN: %check_clang_tidy -std=c++11-or-later %s readability-redundant-casting %t -- -- -fno-delayed-template-parsing |
2 | // RUN: %check_clang_tidy -std=c++11-or-later -check-suffix=,MACROS %s readability-redundant-casting %t -- \ |
3 | // RUN: -config='{CheckOptions: { readability-redundant-casting.IgnoreMacros: false }}' \ |
4 | // RUN: -- -fno-delayed-template-parsing |
5 | // RUN: %check_clang_tidy -std=c++11-or-later -check-suffix=,ALIASES %s readability-redundant-casting %t -- \ |
6 | // RUN: -config='{CheckOptions: { readability-redundant-casting.IgnoreTypeAliases: true }}' \ |
7 | // RUN: -- -fno-delayed-template-parsing |
8 | |
9 | struct A {}; |
10 | struct B : A {}; |
11 | A getA(); |
12 | |
13 | void testRedundantStaticCasting(A& value) { |
14 | A& a1 = static_cast<A&>(value); |
15 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'A' as the sub-expression, remove this casting [readability-redundant-casting] |
16 | // CHECK-MESSAGES: :[[@LINE-3]]:36: note: source type originates from referencing this parameter |
17 | // CHECK-FIXES: {{^}} A& a1 = value; |
18 | } |
19 | |
20 | void testRedundantConstCasting1(A& value) { |
21 | A& a2 = const_cast<A&>(value); |
22 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'A' as the sub-expression, remove this casting [readability-redundant-casting] |
23 | // CHECK-MESSAGES: :[[@LINE-3]]:36: note: source type originates from referencing this parameter |
24 | // CHECK-FIXES: {{^}} A& a2 = value; |
25 | } |
26 | |
27 | void testRedundantConstCasting2(const A& value) { |
28 | const A& a3 = const_cast<const A&>(value); |
29 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant explicit casting to the same type 'const A' as the sub-expression, remove this casting [readability-redundant-casting] |
30 | // CHECK-MESSAGES: :[[@LINE-3]]:42: note: source type originates from referencing this parameter |
31 | // CHECK-FIXES: {{^}} const A& a3 = value; |
32 | } |
33 | |
34 | void testRedundantReinterpretCasting(A& value) { |
35 | A& a4 = reinterpret_cast<A&>(value); |
36 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'A' as the sub-expression, remove this casting [readability-redundant-casting] |
37 | // CHECK-MESSAGES: :[[@LINE-3]]:41: note: source type originates from referencing this parameter |
38 | // CHECK-FIXES: {{^}} A& a4 = value; |
39 | } |
40 | |
41 | void testRedundantCCasting(A& value) { |
42 | A& a5 = (A&)(value); |
43 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'A' as the sub-expression, remove this casting [readability-redundant-casting] |
44 | // CHECK-MESSAGES: :[[@LINE-3]]:31: note: source type originates from referencing this parameter |
45 | // CHECK-FIXES: {{^}} A& a5 = value; |
46 | } |
47 | |
48 | void testDoubleCasting(A& value) { |
49 | A& a6 = static_cast<A&>(reinterpret_cast<A&>(value)); |
50 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'A' as the sub-expression, remove this casting [readability-redundant-casting] |
51 | // CHECK-MESSAGES: :[[@LINE-2]]:27: warning: redundant explicit casting to the same type 'A' as the sub-expression, remove this casting [readability-redundant-casting] |
52 | // CHECK-MESSAGES: :[[@LINE-4]]:27: note: source type originates from referencing this parameter |
53 | // CHECK-FIXES: {{^}} A& a6 = value; |
54 | } |
55 | |
56 | void testDiffrentTypesCast(B& value) { |
57 | A& a7 = static_cast<A&>(value); |
58 | } |
59 | |
60 | void testCastingWithAuto() { |
61 | auto a = getA(); |
62 | A& a8 = static_cast<A&>(a); |
63 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'A' as the sub-expression, remove this casting [readability-redundant-casting] |
64 | // CHECK-MESSAGES: :[[@LINE-3]]:8: note: source type originates from referencing this variable |
65 | // CHECK-FIXES: {{^}} A& a8 = a; |
66 | } |
67 | |
68 | void testCastingWithConstAuto() { |
69 | const auto a = getA(); |
70 | const A& a9 = static_cast<const A&>(a); |
71 | // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant explicit casting to the same type 'const A' as the sub-expression, remove this casting [readability-redundant-casting] |
72 | // CHECK-MESSAGES: :[[@LINE-3]]:14: note: source type originates from referencing this variable |
73 | // CHECK-FIXES: {{^}} const A& a9 = a; |
74 | } |
75 | |
76 | void testCastingWithAutoPtr(A& ptr) { |
77 | auto* a = &ptr; |
78 | A* a10 = static_cast<A*>(a); |
79 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant explicit casting to the same type 'A *' as the sub-expression, remove this casting [readability-redundant-casting] |
80 | // CHECK-MESSAGES: :[[@LINE-3]]:9: note: source type originates from referencing this variable |
81 | // CHECK-FIXES: {{^}} A* a10 = a; |
82 | } |
83 | |
84 | template<typename T> |
85 | void testRedundantTemplateCasting(T& value) { |
86 | A& a = static_cast<A&>(value); |
87 | T& t = static_cast<T&>(value); |
88 | // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant explicit casting to the same type 'T' as the sub-expression, remove this casting [readability-redundant-casting] |
89 | // CHECK-MESSAGES: :[[@LINE-4]]:38: note: source type originates from referencing this parameter |
90 | // CHECK-FIXES: {{^}} T& t = value; |
91 | } |
92 | |
93 | void testTemplate() { |
94 | A value; |
95 | testRedundantTemplateCasting(value); |
96 | } |
97 | |
98 | void testValidRefConstCast() { |
99 | const auto a = getA(); |
100 | A& a11 = const_cast<A&>(a); |
101 | } |
102 | |
103 | void testValidPtrConstCast(const A* ptr) { |
104 | A* a12 = const_cast<A*>(ptr); |
105 | } |
106 | |
107 | #define CAST(X) static_cast<int>(X) |
108 | |
109 | void testMacroCasting(int value) { |
110 | int a = CAST(value); |
111 | // CHECK-MESSAGES-MACROS: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'int' as the sub-expression, remove this casting [readability-redundant-casting] |
112 | } |
113 | |
114 | #define PTR_NAME name |
115 | |
116 | void testMacroCasting(A* PTR_NAME) { |
117 | A* a13 = static_cast<A*>(PTR_NAME); |
118 | // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant explicit casting to the same type 'A *' as the sub-expression, remove this casting [readability-redundant-casting] |
119 | // CHECK-FIXES: {{^}} A* a13 = PTR_NAME; |
120 | } |
121 | |
122 | struct CastBool { |
123 | operator bool() const { |
124 | return true; |
125 | } |
126 | }; |
127 | |
128 | void testUserOperatorCast(const CastBool& value) { |
129 | bool b = static_cast<bool>(value); |
130 | } |
131 | |
132 | using TypeA = A; |
133 | |
134 | void testTypedefCast(A& value) { |
135 | TypeA& a = static_cast<TypeA&>(value); |
136 | // CHECK-MESSAGES-ALIASES: :[[@LINE-1]]:14: warning: redundant explicit casting to the same type 'TypeA' (aka 'A') as the sub-expression, remove this casting [readability-redundant-casting] |
137 | // CHECK-FIXES-ALIASES: {{^}} TypeA& a = value; |
138 | } |
139 | |
140 | void testTypedefCast2(TypeA& value) { |
141 | A& a = static_cast<A&>(value); |
142 | // CHECK-MESSAGES-ALIASES: :[[@LINE-1]]:10: warning: redundant explicit casting to the same type 'A' as the sub-expression, remove this casting [readability-redundant-casting] |
143 | // CHECK-FIXES-ALIASES: {{^}} A& a = value; |
144 | } |
145 | |
146 | void testFunctionalCastWithPrimitive(int a) { |
147 | int b = int(a); |
148 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'int' as the sub-expression, remove this casting [readability-redundant-casting] |
149 | // CHECK-FIXES: {{^}} int b = a; |
150 | } |
151 | |
152 | void testFunctionalCastWithInitExpr(unsigned a) { |
153 | unsigned b = ~unsigned{!a}; |
154 | unsigned c = unsigned{0}; |
155 | } |
156 | |
157 | void testBinaryOperator(char c) { |
158 | int a = int(c - 'C'); |
159 | } |
160 | |
161 | struct BIT { |
162 | bool b:1; |
163 | }; |
164 | |
165 | template<typename ...Args> |
166 | void make(Args&& ...); |
167 | |
168 | void testBinaryOperator(BIT b) { |
169 | make((bool)b.b); |
170 | } |
171 | |
172 | struct Class { |
173 | using Iterator = const char*; |
174 | |
175 | Iterator begin() { |
176 | return static_cast<Iterator>(first()); |
177 | // CHECK-MESSAGES-ALIASES: :[[@LINE-1]]:12: warning: redundant explicit casting to the same type 'Iterator' (aka 'const char *') as the sub-expression, remove this casting [readability-redundant-casting] |
178 | // CHECK-MESSAGES-ALIASES: :[[@LINE+4]]:15: note: source type originates from the invocation of this method |
179 | // CHECK-FIXES-ALIASES: {{^}} return first(); |
180 | } |
181 | |
182 | const char* first(); |
183 | }; |
184 | |
185 | void testAddOperation(int aa, int bb) { |
186 | int c = static_cast<int>(aa + bb) * aa; |
187 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'int' as the sub-expression, remove this casting [readability-redundant-casting] |
188 | // CHECK-FIXES: {{^}} int c = (aa + bb) * aa; |
189 | } |
190 | |
191 | void testAddOperationWithParen(int a, int b) { |
192 | int c = static_cast<int>((a+b))*a; |
193 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'int' as the sub-expression, remove this casting [readability-redundant-casting] |
194 | // CHECK-FIXES: {{^}} int c = (a+b)*a; |
195 | } |
196 | |
197 | void testRValueCast(int&& a) { |
198 | int&& b = static_cast<int&&>(a); |
199 | int&& c = static_cast<int&&>(10); |
200 | // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant explicit casting to the same type 'int' as the sub-expression, remove this casting [readability-redundant-casting] |
201 | // CHECK-FIXES: {{^}} int&& c = 10; |
202 | } |
203 | |
204 | template <int V> |
205 | void testRedundantNTTPCasting() { |
206 | int a = static_cast<int>(V); |
207 | // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant explicit casting to the same type 'int' as the sub-expression, remove this casting [readability-redundant-casting] |
208 | // CHECK-MESSAGES: :[[@LINE-4]]:15: note: source type originates from referencing this non-type template parameter |
209 | // CHECK-FIXES: {{^}} int a = V; |
210 | } |
211 | |
212 | template <typename T, T V> |
213 | void testValidNTTPCasting() { |
214 | int a = static_cast<int>(V); |
215 | } |
216 | |
217 | template <typename T, T V> |
218 | void testRedundantDependentNTTPCasting() { |
219 | T a = static_cast<T>(V); |
220 | // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant explicit casting to the same type 'T' as the sub-expression, remove this casting [readability-redundant-casting] |
221 | // CHECK-MESSAGES: :[[@LINE-4]]:25: note: source type originates from referencing this non-type template parameter |
222 | // CHECK-FIXES: {{^}} T a = V; |
223 | } |
224 | |