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
9struct A {};
10struct B : A {};
11A getA();
12
13void 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
20void 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
27void 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
34void 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
41void 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
48void 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
56void testDiffrentTypesCast(B& value) {
57 A& a7 = static_cast<A&>(value);
58}
59
60void 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
68void 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
76void 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
84template<typename T>
85void 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
93void testTemplate() {
94 A value;
95 testRedundantTemplateCasting(value);
96}
97
98void testValidRefConstCast() {
99 const auto a = getA();
100 A& a11 = const_cast<A&>(a);
101}
102
103void testValidPtrConstCast(const A* ptr) {
104 A* a12 = const_cast<A*>(ptr);
105}
106
107#define CAST(X) static_cast<int>(X)
108
109void 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
116void 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
122struct CastBool {
123 operator bool() const {
124 return true;
125 }
126};
127
128void testUserOperatorCast(const CastBool& value) {
129 bool b = static_cast<bool>(value);
130}
131
132using TypeA = A;
133
134void 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
140void 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
146void 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
152void testFunctionalCastWithInitExpr(unsigned a) {
153 unsigned b = ~unsigned{!a};
154 unsigned c = unsigned{0};
155}
156
157void testBinaryOperator(char c) {
158 int a = int(c - 'C');
159}
160
161struct BIT {
162 bool b:1;
163};
164
165template<typename ...Args>
166void make(Args&& ...);
167
168void testBinaryOperator(BIT b) {
169 make((bool)b.b);
170}
171
172struct 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
185void 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
191void 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
197void 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
204template <int V>
205void 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
212template <typename T, T V>
213void testValidNTTPCasting() {
214 int a = static_cast<int>(V);
215}
216
217template <typename T, T V>
218void 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

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