Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / compilerplugins / clang / test / redundantcast.cxx
blob0c1087ab32af575ff5397406fea7dd562abdc333
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sal/config.h>
12 #include <cstddef>
14 #include <sal/types.h>
16 #include "redundantcast.hxx"
18 void f1(char *) {}
19 void f2(char const *) {}
21 struct D: S {};
23 enum Enum1 { X };
25 void testConstCast() {
26 char * p1;
27 char const * p2;
28 p1 = nullptr;
29 p2 = "";
30 f1(const_cast<char *>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *' prvalue [loplugin:redundantcast]}}
31 f1(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *const' prvalue [loplugin:redundantcast]}}
32 f1(const_cast<char *>(p2));
33 f1(const_cast<char * const>(p2));
34 f2(const_cast<char *>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *' prvalue [loplugin:redundantcast]}}
35 f2(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *const' prvalue [loplugin:redundantcast]}}
36 f2(const_cast<char const *>(p1));
37 f2(const_cast<char const * const>(p1));
38 f2(const_cast<char *>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'char *', result is implicitly cast to 'const char *' [loplugin:redundantcast]}}
39 f2(const_cast<char * const>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'char *', result is implicitly cast to 'const char *' [loplugin:redundantcast]}}
40 f2(const_cast<char const *>(p2)); // expected-error {{redundant const_cast from 'const char *' lvalue to 'const char *' prvalue [loplugin:redundantcast]}}
41 f2(const_cast<char const * const>(p2)); // expected-error {{redundant const_cast from 'const char *' lvalue to 'const char *const' prvalue [loplugin:redundantcast]}}
43 void * vp = nullptr;
44 (void) const_cast<char *>(static_cast<char const *>(vp)); // expected-error {{redundant static_cast/const_cast combination from 'void *' via 'const char *' to 'char *' [loplugin:redundantcast]}}
45 (void) const_cast<char *>(static_cast<char const *>(nullptr)); // expected-error-re {{redundant static_cast/const_cast combination from '{{(std::)?}}nullptr_t' via 'const char *' to 'char *' [loplugin:redundantcast]}}
46 (void) const_cast<S &>(static_cast<S const &>(D{})); // expected-error {{redundant static_cast/const_cast combination from 'D' via 'const S &' to 'S &' [loplugin:redundantcast]}}
48 S const s{};
49 const_cast<S &>(s).f1();
50 const_cast<S &>(s).f2(); // expected-error {{redundant const_cast from 'const S' to 'S', result is implicitly cast to 'const S' [loplugin:redundantcast]}}
51 const_cast<S &>(s).f3();
52 s.f3();
54 // non-class lvalue, non-const:
55 int ni{};
56 // (void) const_cast<int>(ni);
57 (void) const_cast<int &>(ni); // expected-error {{redundant const_cast from 'int' lvalue to 'int &' lvalue [loplugin:redundantcast]}}
58 (void) const_cast<int &&>(ni);
59 // (void) const_cast<int const>(ni);
60 (void) const_cast<int const &>(ni);
61 (void) const_cast<int const &&>(ni);
63 // non-class lvalue, const:
64 int const ci{};
65 // (void) const_cast<int>(ci);
66 (void) const_cast<int &>(ci);
67 (void) const_cast<int &&>(ci);
68 // (void) const_cast<int const>(ci);
69 (void) const_cast<int const &>(ci); // expected-error {{redundant const_cast from 'const int' lvalue to 'const int &' lvalue [loplugin:redundantcast]}}
70 (void) const_cast<int const &&>(ci);
72 // non-class xvalue, non-const:
73 // (void) const_cast<int>(nix());
74 // (void) const_cast<int &>(nix());
75 (void) const_cast<int &&>(nix()); // expected-error {{redundant const_cast from 'int' xvalue to 'int &&' xvalue [loplugin:redundantcast]}}
76 // (void) const_cast<int const>(nix());
77 // (void) const_cast<int const &>(nix());
78 (void) const_cast<int const &&>(nix());
80 // non-class xvalue, const:
81 // (void) const_cast<int>(cix());
82 // (void) const_cast<int &>(cix());
83 (void) const_cast<int &&>(cix());
84 // (void) const_cast<int const>(cix());
85 // (void) const_cast<int const &>(cix());
86 (void) const_cast<int const &&>(cix()); // expected-error {{redundant const_cast from 'const int' xvalue to 'const int &&' xvalue [loplugin:redundantcast]}}
88 // non-class prvalue, non-const:
89 // (void) const_cast<int>(nir());
90 // (void) const_cast<int &>(nir());
91 // (void) const_cast<int &&>(nir());
92 // (void) const_cast<int const>(nir());
93 // (void) const_cast<int const &>(nir());
94 // (void) const_cast<int const &&>(nir());
96 // non-class prvalue, const:
97 // (void) const_cast<int>(cir());
98 // (void) const_cast<int &>(cir());
99 // (void) const_cast<int &&>(cir());
100 // (void) const_cast<int const>(cir());
101 // (void) const_cast<int const &>(cir());
102 // (void) const_cast<int const &&>(cir());
104 // class lvalue, non-const:
105 S ns{};
106 // (void) const_cast<S>(ns);
107 (void) const_cast<S &>(ns); // expected-error {{redundant const_cast from 'S' lvalue to 'S &' lvalue [loplugin:redundantcast]}}
108 (void) const_cast<S &&>(ns);
109 // (void) const_cast<S const>(ns);
110 (void) const_cast<S const &>(ns);
111 (void) const_cast<S const &&>(ns);
113 // class lvalue, const:
114 S const cs{};
115 // (void) const_cast<S>(cs);
116 (void) const_cast<S &>(cs);
117 (void) const_cast<S &&>(cs);
118 // (void) const_cast<S const>(cs);
119 (void) const_cast<S const &>(cs); // expected-error {{redundant const_cast from 'const S' lvalue to 'const S &' lvalue [loplugin:redundantcast]}}
120 (void) const_cast<S const &&>(cs);
122 // class xvalue, non-const:
123 // (void) const_cast<S>(nsx());
124 // (void) const_cast<S &>(nsx());
125 (void) const_cast<S &&>(nsx()); // expected-error {{redundant const_cast from 'S' xvalue to 'S &&' xvalue [loplugin:redundantcast]}}
126 // (void) const_cast<S const>(nsx());
127 // (void) const_cast<S const &>(nsx());
128 (void) const_cast<S const &&>(nsx());
130 // class xvalue, const:
131 // (void) const_cast<S>(csx());
132 // (void) const_cast<S &>(csx());
133 (void) const_cast<S &&>(csx());
134 // (void) const_cast<S const>(csx());
135 // (void) const_cast<S const &>(csx());
136 (void) const_cast<S const &&>(csx()); // expected-error {{redundant const_cast from 'const S' xvalue to 'const S &&' xvalue [loplugin:redundantcast]}}
138 // class prvalue, non-const:
139 // (void) const_cast<S>(nsr());
140 // (void) const_cast<S &>(nsr());
141 (void) const_cast<S &&>(nsr());
142 // (void) const_cast<S const>(nsr());
143 // (void) const_cast<S const &>(nsr());
144 (void) const_cast<S const &&>(nsr());
146 // class prvalue, const:
147 // (void) const_cast<S>(csr());
148 // (void) const_cast<S &>(csr());
149 (void) const_cast<S &&>(csr());
150 // (void) const_cast<S const>(csr());
151 // (void) const_cast<S const &>(csr());
152 (void) const_cast<S const &&>(csr());
155 void testStaticCast() {
156 // non-class lvalue, non-const:
157 int ni{};
158 (void) static_cast<int>(ni); // expected-error {{static_cast from 'int' lvalue to 'int' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
159 /* => */ (void) int(ni);
160 (void) static_cast<int &>(ni); // expected-error {{static_cast from 'int' lvalue to 'int &' lvalue is redundant [loplugin:redundantcast]}}
161 (void) static_cast<int &&>(ni);
162 (void) static_cast<int const>(ni); // expected-error {{in static_cast from 'int' lvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}}
163 /* => */ (void) static_cast<int>(ni); // expected-error {{static_cast from 'int' lvalue to 'int' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
164 /* => */ (void) int(ni);
165 (void) static_cast<int const &>(ni); // expected-error {{static_cast from 'int' lvalue to 'const int &' lvalue should be written as const_cast [loplugin:redundantcast]}}
166 /* => */ (void) const_cast<int const &>(ni);
167 (void) static_cast<int const &&>(ni); // expected-error {{static_cast from 'int' lvalue to 'const int &&' xvalue should be written as const_cast [loplugin:redundantcast]}}
168 /* => */ (void) const_cast<int const &&>(ni);
170 // non-class lvalue, const:
171 int const ci{};
172 (void) static_cast<int>(ci); // expected-error {{static_cast from 'const int' lvalue to 'int' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
173 /* => */ (void) int(ci);
174 // (void) static_cast<int &>(ci);
175 // (void) static_cast<int &&>(ci);
176 (void) static_cast<int const>(ci); // expected-error {{in static_cast from 'const int' lvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}}
177 /* => */ (void) static_cast<int>(ci); // expected-error {{static_cast from 'const int' lvalue to 'int' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
178 /* => */ (void) int(ci);
179 (void) static_cast<int const &>(ci); // expected-error {{static_cast from 'const int' lvalue to 'const int &' lvalue is redundant [loplugin:redundantcast]}}
180 (void) static_cast<int const &&>(ci);
182 // non-class xvalue, non-const:
183 (void) static_cast<int>(nix()); // expected-error {{static_cast from 'int' xvalue to 'int' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
184 /* => */ (void) int(nix());
185 // (void) static_cast<int &>(nix());
186 (void) static_cast<int &&>(nix()); // expected-error {{static_cast from 'int' xvalue to 'int &&' xvalue is redundant [loplugin:redundantcast]}}
187 (void) static_cast<int const>(nix()); // expected-error {{in static_cast from 'int' xvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}}
188 /* => */ (void) static_cast<int>(nix()); // expected-error {{static_cast from 'int' xvalue to 'int' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
189 (void) static_cast<int const &>(nix());
190 (void) static_cast<int const &&>(nix()); // expected-error {{static_cast from 'int' xvalue to 'const int &&' xvalue should be written as const_cast [loplugin:redundantcast]}}
191 /* => */ (void) const_cast<int const &&>(nix());
193 // non-class xvalue, const:
194 (void) static_cast<int>(cix()); // expected-error {{static_cast from 'const int' xvalue to 'int' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
195 /* => */ (void) int(cix());
196 // (void) static_cast<int &>(cix());
197 // (void) static_cast<int &&>(cix());
198 (void) static_cast<int const>(cix()); // expected-error {{in static_cast from 'const int' xvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}}
199 /* => */ (void) static_cast<int>(cix()); // expected-error {{static_cast from 'const int' xvalue to 'int' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
200 /* => */ (void) int(cix());
201 (void) static_cast<int const &>(cix());
202 (void) static_cast<int const &&>(cix()); // expected-error {{static_cast from 'const int' xvalue to 'const int &&' xvalue is redundant [loplugin:redundantcast]}}
204 // non-class prvalue, non-const:
205 (void) static_cast<int>(nir()); // expected-error {{static_cast from 'int' prvalue to 'int' prvalue is redundant [loplugin:redundantcast]}}
206 // (void) static_cast<int &>(nir());
207 (void) static_cast<int &&>(nir());
208 (void) static_cast<int const>(nir()); // expected-error {{in static_cast from 'int' prvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}}
209 /* => */ (void) static_cast<int>(nir()); // expected-error {{static_cast from 'int' prvalue to 'int' prvalue is redundant [loplugin:redundantcast]}}
210 (void) static_cast<int const &>(nir()); // expected-error {{static_cast from 'int' prvalue to 'const int &' lvalue is redundant [loplugin:redundantcast]}}
211 (void) static_cast<int const &&>(nir());
213 // non-class prvalue, const:
214 (void) static_cast<int>(cir()); // expected-error {{static_cast from 'int' prvalue to 'int' prvalue is redundant [loplugin:redundantcast]}}
215 // (void) static_cast<int &>(cir());
216 (void) static_cast<int &&>(cir());
217 (void) static_cast<int const>(cir()); // expected-error {{in static_cast from 'int' prvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}}
218 /* => */ (void) static_cast<int>(cir()); // expected-error {{static_cast from 'int' prvalue to 'int' prvalue is redundant [loplugin:redundantcast]}}
219 (void) static_cast<int const &>(cir()); // expected-error {{static_cast from 'int' prvalue to 'const int &' lvalue is redundant [loplugin:redundantcast]}}
220 (void) static_cast<int const &&>(cir());
222 // class lvalue, non-const:
223 S ns{};
224 (void) static_cast<S>(ns); // expected-error {{static_cast from 'S' lvalue to 'S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
225 /* => */ (void) S(ns);
226 (void) static_cast<S &>(ns); // expected-error {{static_cast from 'S' lvalue to 'S &' lvalue is redundant [loplugin:redundantcast]}}
227 (void) static_cast<S &&>(ns);
228 (void) static_cast<S const>(ns); // expected-error {{static_cast from 'S' lvalue to 'const S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
229 /* => */ using CS = const S; (void) CS(ns);
230 (void) static_cast<S const &>(ns); // expected-error {{static_cast from 'S' lvalue to 'const S &' lvalue should be written as const_cast [loplugin:redundantcast]}}
231 /* => */ (void) const_cast<S const &>(ns);
232 (void) static_cast<S const &&>(ns); // expected-error {{static_cast from 'S' lvalue to 'const S &&' xvalue should be written as const_cast [loplugin:redundantcast]}}
233 /* => */ (void) const_cast<S const &&>(ns);
235 // class lvalue, const:
236 S const cs{};
237 (void) static_cast<S>(cs); // expected-error {{static_cast from 'const S' lvalue to 'S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
238 /* => */ (void) S(cs);
239 // (void) static_cast<S &>(cs);
240 // (void) static_cast<S &&>(cs);
241 (void) static_cast<S const>(cs); // expected-error {{static_cast from 'const S' lvalue to 'const S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
242 /* => */ (void) CS(cs);
243 (void) static_cast<S const &>(cs); // expected-error {{static_cast from 'const S' lvalue to 'const S &' lvalue is redundant [loplugin:redundantcast]}}
244 (void) static_cast<S const &&>(cs);
246 // class xvalue, non-const:
247 (void) static_cast<S>(nsx()); // expected-error {{static_cast from 'S' xvalue to 'S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
248 /* => */ (void) S(nsx());
249 // (void) static_cast<S &>(nsx());
250 (void) static_cast<S &&>(nsx()); // expected-error {{static_cast from 'S' xvalue to 'S &&' xvalue is redundant [loplugin:redundantcast]}}
251 (void) static_cast<S const>(nsx()); // expected-error {{static_cast from 'S' xvalue to 'const S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
252 /* => */ (void) CS(nsx());
253 (void) static_cast<S const &>(nsx());
254 (void) static_cast<S const &&>(nsx()); // expected-error {{static_cast from 'S' xvalue to 'const S &&' xvalue should be written as const_cast [loplugin:redundantcast]}}
255 /* => */ (void) const_cast<S const &&>(nsx());
257 // class xvalue, const:
258 (void) static_cast<S>(csx()); // expected-error {{static_cast from 'const S' xvalue to 'S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
259 /* => */ (void) S(csx());
260 // (void) static_cast<S &>(csx());
261 // (void) static_cast<S &&>(csx());
262 (void) static_cast<S const>(csx()); // expected-error {{static_cast from 'const S' xvalue to 'const S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
263 /* => */ (void) CS(csx());
264 (void) static_cast<S const &>(csx());
265 (void) static_cast<S const &&>(csx()); // expected-error {{static_cast from 'const S' xvalue to 'const S &&' xvalue is redundant [loplugin:redundantcast]}}
267 // class prvalue, non-const:
268 (void) static_cast<S>(nsr()); // expected-error {{static_cast from 'S' prvalue to 'S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
269 /* => */ (void) S(nsr());
270 // (void) static_cast<S &>(nsr());
271 (void) static_cast<S &&>(nsr());
272 (void) static_cast<S const>(nsr()); // expected-error {{static_cast from 'S' prvalue to 'const S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
273 /* => */ (void) CS(nsr());
274 (void) static_cast<S const &>(nsr()); // expected-error {{static_cast from 'S' prvalue to 'const S &' lvalue is redundant [loplugin:redundantcast]}}
275 (void) static_cast<S const &&>(nsr()); // expected-error {{static_cast from 'S' prvalue to 'const S &&' xvalue should be written as const_cast [loplugin:redundantcast]}}
276 /* => */ (void) const_cast<S const &&>(nsr());
278 // class prvalue, const:
279 (void) static_cast<S>(csr()); // expected-error {{static_cast from 'const S' prvalue to 'S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
280 /* => */ (void) S(csr());
281 // (void) static_cast<S &>(csr());
282 // (void) static_cast<S &&>(csr());
283 (void) static_cast<S const>(csr()); // expected-error {{static_cast from 'const S' prvalue to 'const S' prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
284 /* => */ (void) CS(csr());
285 (void) static_cast<S const &>(csr()); // expected-error {{static_cast from 'const S' prvalue to 'const S &' lvalue is redundant [loplugin:redundantcast]}}
286 (void) static_cast<S const &&>(csr());
289 int & testReturnStaticCast(int && x) { return static_cast<int &>(x); }
291 void testFunctionalCast() {
292 (void) int(nir()); // expected-error {{redundant functional cast from 'int' to 'int' [loplugin:redundantcast]}}
293 (void) S(nsr());
296 void testCStyleCast() {
297 Enum1 e = (Enum1)Enum1::X; // expected-error {{redundant cstyle cast from 'Enum1' to 'Enum1' [loplugin:redundantcast]}}
298 (void)e;
301 template<typename T>
302 struct EnumItemInterface {
303 T GetValue() { return static_cast<T>(0); }
305 class Enum1Item : public EnumItemInterface<Enum1> {
307 bool testCStyleCastOfTemplateMethodResult(Enum1Item* item) {
308 return (Enum1)item->GetValue() == Enum1::X; // expected-error {{redundant cstyle cast from 'Enum1' to 'Enum1' [loplugin:redundantcast]}}
311 using T1 = int;
312 T1 nt1r() { return 0; }
313 void testArithmeticTypedefs() {
314 (void) static_cast<T1>(nir());
315 (void) T1(nir());
316 (void) (T1) nir();
317 (void) static_cast<int>(nt1r());
318 (void) int(nt1r());
319 (void) (int) nt1r();
320 using T2 = T1;
321 (void) static_cast<T2>(nt1r());
322 (void) T2(nt1r());
323 (void) (T2) nt1r();
324 (void) static_cast<T1>(nt1r()); // expected-error {{redundant}}
325 (void) T1(nt1r()); // expected-error {{redundant}}
326 (void) (T1) nt1r(); // expected-error {{redundant}}
328 T1 const c{};
329 (void) static_cast<T1>(c); // expected-error {{redundant}}
332 void testReinterpretCast() {
333 int * p;
334 (void) reinterpret_cast<int *>(p); // expected-error {{redundant reinterpret_cast from 'int *' to 'int *' [loplugin:redundantcast]}}
337 void testReinterpretConstCast() {
338 int n = 0;
339 (void) reinterpret_cast<std::size_t>((const_cast<int const *>(&n))); // expected-error-re {{redundant const_cast from 'int *' to 'const int *' within reinterpret_cast to fundamental type 'std::size_t' (aka 'unsigned {{.+}}') [loplugin:redundantcast]}}
342 void testSuspiciousReinterpretCast() {
343 D * p;
344 // expected-error@+1 {{suspicious reinterpret_cast from derived 'D *' to base 'S *', maybe this was meant to be a static_cast [loplugin:redundantcast]}}
345 (void) reinterpret_cast<S *>(p);
346 (void) reinterpret_cast<sal_uIntPtr>(p); // expected no error
349 void testDynamicCast() {
351 struct S1 { virtual ~S1(); };
352 struct S2 final: S1 {};
353 struct S3: S1 {};
355 S1 * s1 = nullptr;
356 S2 * s2 = nullptr;
357 S3 * s3 = nullptr;
359 (void) dynamic_cast<void *>(s1);
360 (void) dynamic_cast<void const *>(s1);
361 (void) dynamic_cast<S2 *>(s1);
362 (void) dynamic_cast<S2 &>(*s1);
363 (void) dynamic_cast<S1 *>(s2); // expected-error {{redundant dynamic upcast from 'S2 *' to 'S1 *' [loplugin:redundantcast]}}
364 (void) dynamic_cast<S1 &>(*s2); // expected-error {{redundant dynamic upcast from 'S2' to 'S1 &' [loplugin:redundantcast]}}
365 (void) dynamic_cast<S2 *>(s2); // expected-error {{redundant dynamic cast from 'S2 *' to 'S2 *' [loplugin:redundantcast]}}
366 (void) dynamic_cast<S2 &>(*s2); // expected-error {{redundant dynamic cast from 'S2' to 'S2 &' [loplugin:redundantcast]}}
367 (void) dynamic_cast<S3 *>(s2);
368 (void) dynamic_cast<S3 &>(*s2);
369 (void) dynamic_cast<const S2 *>(s2); // expected-error {{redundant dynamic cast from 'S2 *' to 'const S2 *' [loplugin:redundantcast]}}
370 (void) dynamic_cast<const S2 &>(*s2); // expected-error {{redundant dynamic cast from 'S2' to 'const S2 &' [loplugin:redundantcast]}}
371 (void) dynamic_cast<S1 *>(s3); // expected-error {{redundant dynamic upcast from 'S3 *' to 'S1 *' [loplugin:redundantcast]}}
372 (void) dynamic_cast<S1&>(*s3); // expected-error {{redundant dynamic upcast from 'S3' to 'S1 &' [loplugin:redundantcast]}}
374 S1 const * c1 = nullptr;
375 S2 const * c2 = nullptr;
376 S3 const * c3 = nullptr;
378 (void) dynamic_cast<void const *>(c1);
379 (void) dynamic_cast<S2 const *>(c1);
380 (void) dynamic_cast<S2 const &>(*c1);
381 (void) dynamic_cast<S1 const *>(c2); // expected-error {{redundant dynamic upcast from 'const S2 *' to 'const S1 *' [loplugin:redundantcast]}}
382 (void) dynamic_cast<S1 const &>(*c2); // expected-error {{redundant dynamic upcast from 'const S2' to 'const S1 &' [loplugin:redundantcast]}}
384 (void) dynamic_cast<S2 const *>(c2); // expected-error {{redundant dynamic cast from 'const S2 *' to 'const S2 *' [loplugin:redundantcast]}}
385 (void) dynamic_cast<S2 const &>(*c2); // expected-error {{redundant dynamic cast from 'const S2' to 'const S2 &' [loplugin:redundantcast]}}
386 (void) dynamic_cast<S3 const *>(c2);
387 (void) dynamic_cast<S3 const &>(*c2);
388 (void) dynamic_cast<S1 const *>(c3); // expected-error {{redundant dynamic upcast from 'const S3 *' to 'const S1 *' [loplugin:redundantcast]}}
389 (void) dynamic_cast<S1 const&>(*c3); // expected-error {{redundant dynamic upcast from 'const S3' to 'const S1 &' [loplugin:redundantcast]}}
392 void overload(int);
393 void overload(long);
394 void nonOverload();
396 struct Overload {
397 int overload();
398 long overload() const;
399 void nonOverload();
402 void testOverloadResolution() {
403 (void) static_cast<void (*)(long)>(overload);
404 (void) static_cast<void (*)(long)>((overload));
405 (void) static_cast<void (*)(long)>(&overload);
406 (void) static_cast<void (*)(long)>((&overload));
407 (void) static_cast<void (*)(long)>(&((overload)));
408 (void) static_cast<void (*)()>(nonOverload); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
409 (void) static_cast<void (*)()>((nonOverload)); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
410 (void) static_cast<void (*)()>(&nonOverload); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
411 (void) static_cast<void (*)()>((&nonOverload)); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
412 (void) static_cast<void (*)()>(&((nonOverload))); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
413 (void) static_cast<long (Overload::*)() const>(&Overload::overload);
414 (void) static_cast<void (Overload::*)()>(&Overload::nonOverload); // expected-error {{static_cast from 'void (Overload::*)()' prvalue to 'void (Overload::*)()' prvalue is redundant [loplugin:redundantcast]}}
416 using OverloadFn = void (*)(long);
417 (void) OverloadFn(overload);
418 using NonOverloadFn = void (*)();
419 (void) NonOverloadFn(nonOverload); // expected-error {{redundant functional cast from 'void (*)()' to 'NonOverloadFn' (aka 'void (*)()') [loplugin:redundantcast]}}
420 using OverloadMemFn = long (Overload::*)() const;
421 (void) OverloadMemFn(&Overload::overload);
422 using NonOverloadMemFn = void (Overload::*)();
423 (void) NonOverloadMemFn(&Overload::nonOverload); // expected-error {{redundant functional cast from 'void (Overload::*)()' to 'NonOverloadMemFn' (aka 'void (Overload::*)()') [loplugin:redundantcast]}}
426 void testIntermediaryStaticCast() {
427 int n = 0;
428 n = static_cast<double>(n); // expected-error {{suspicious static_cast from 'int' to 'double', result is implicitly cast to 'int' [loplugin:redundantcast]}}
429 n = double(n); // expected-error {{suspicious functional cast from 'int' to 'double', result is implicitly cast to 'int' [loplugin:redundantcast]}}
430 double d = 0.0;
431 d = static_cast<int>(d) + 1.0; // expected-error {{suspicious static_cast from 'double' to 'int', result is implicitly cast to 'double' [loplugin:redundantcast]}}
432 d = int(d) + 1.0; // expected-error {{suspicious functional cast from 'double' to 'int', result is implicitly cast to 'double' [loplugin:redundantcast]}}
435 void testArrayDecay() {
436 (void) static_cast<char const *>(""); // expected-error-re {{redundant static_cast from 'const char{{ ?}}[1]' to 'const char *' [loplugin:redundantcast]}}
437 (void) reinterpret_cast<char const *>(""); // expected-error-re {{redundant reinterpret_cast from 'const char{{ ?}}[1]' to 'const char *' [loplugin:redundantcast]}}
438 (void) reinterpret_cast<char const *>(u8"");
441 void testNew() {
442 class A {};
443 class B : public A {};
444 A* p = static_cast<A*>(new B); // expected-error {{redundant static_cast from 'B *' to 'A *' [loplugin:redundantcast]}}
445 (void)p;
446 // no warning expected for resolving-ambiguity cast
447 class C : public A {};
448 class D : public B, public C {};
449 p = static_cast<B*>(new D);
450 // no warning expected for down-cast
451 auto p2 = static_cast<B*>(p);
452 (void)p2;
455 using F = void (*)();
456 auto testNullFunctionPointer(int i, F p) {
457 switch (i) {
458 case 0:
459 return static_cast<F>(nullptr);
460 case 1:
461 return F(nullptr);
462 default:
463 return p;
467 void testSalIntTypes() {
468 sal_Int16 const n = 0;
469 (void) static_cast<sal_Int16>(n); // expected-error-re {{static_cast from 'const sal_Int16' (aka 'const {{.+}}') lvalue to 'sal_Int16' (aka '{{.+}}') prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
470 (void) static_cast<::sal_Int16>(n); // expected-error-re {{static_cast from 'const sal_Int16' (aka 'const {{.+}}') lvalue to '::sal_Int16' (aka '{{.+}}') prvalue is redundant or should be written as an explicit construction of a temporary [loplugin:redundantcast]}}
471 (void) static_cast<short>(n); // doesn't warn, even if 'sal_Int16' is 'short'
472 using Other = sal_Int16;
473 (void) static_cast<Other>(n); // doesn't warn either
476 int main() {
477 testConstCast();
478 testStaticCast();
479 testFunctionalCast();
480 testCStyleCast();
481 testCStyleCastOfTemplateMethodResult(nullptr);
482 testReinterpretCast();
483 testReinterpretConstCast();
484 testDynamicCast();
485 testIntermediaryStaticCast();
486 testArrayDecay();
487 testSalIntTypes();
490 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */