/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <sal/config.h>
#include <cstddef>
#include <sal/types.h>
#include"redundantcast.hxx"
void f1(char *) {} void f2(charconst *) {}
struct D: S {};
enum Enum1 { X };
void testConstCast() { char * p1; charconst * p2;
p1 = nullptr;
p2 = "";
f1(const_cast<char *>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *' prvalue [loplugin:redundantcast]}}
f1(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *const' prvalue [loplugin:redundantcast]}}
f1(const_cast<char *>(p2));
f1(const_cast<char * const>(p2));
f2(const_cast<char *>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *' prvalue [loplugin:redundantcast]}}
f2(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' lvalue to 'char *const' prvalue [loplugin:redundantcast]}}
f2(const_cast<charconst *>(p1));
f2(const_cast<charconst * const>(p1));
f2(const_cast<char *>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'char *', result is implicitly cast to 'const char *' [loplugin:redundantcast]}}
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]}}
f2(const_cast<charconst *>(p2)); // expected-error {{redundant const_cast from 'const char *' lvalue to 'const char *' prvalue [loplugin:redundantcast]}}
f2(const_cast<charconst * const>(p2)); // expected-error {{redundant const_cast from 'const char *' lvalue to 'const char *const' prvalue [loplugin:redundantcast]}}
void * vp = nullptr;
(void) const_cast<char *>(static_cast<charconst *>(vp)); // expected-error {{redundant static_cast/const_cast combination from 'void *' via 'const char *' to 'char *' [loplugin:redundantcast]}}
(void) const_cast<char *>(static_cast<charconst *>(nullptr)); // expected-error-re {{redundant static_cast/const_cast combination from '{{(std::)?}}nullptr_t' via 'const char *' to 'char *' [loplugin:redundantcast]}}
(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]}}
S const s{}; const_cast<S &>(s).f1(); const_cast<S &>(s).f2(); // expected-error {{redundant const_cast from 'const S' to 'S', result is implicitly cast to 'const S' [loplugin:redundantcast]}} const_cast<S &>(s).f3();
s.f3();
// non-class lvalue, non-const: int ni{}; // (void) const_cast<int>(ni);
(void) const_cast<int &>(ni); // expected-error {{redundant const_cast from 'int' lvalue to 'int &' lvalue [loplugin:redundantcast]}}
(void) const_cast<int &&>(ni); // (void) const_cast<int const>(ni);
(void) const_cast<intconst &>(ni);
(void) const_cast<intconst &&>(ni);
// non-class lvalue, const: intconst ci{}; // (void) const_cast<int>(ci);
(void) const_cast<int &>(ci);
(void) const_cast<int &&>(ci); // (void) const_cast<int const>(ci);
(void) const_cast<intconst &>(ci); // expected-error {{redundant const_cast from 'const int' lvalue to 'const int &' lvalue [loplugin:redundantcast]}}
(void) const_cast<intconst &&>(ci);
void testStaticCast() { // non-class lvalue, non-const: int ni{};
(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]}} /* => */ (void) int(ni);
(void) static_cast<int &>(ni); // expected-error {{static_cast from 'int' lvalue to 'int &' lvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<int &&>(ni);
(void) static_cast<intconst>(ni); // expected-error {{in static_cast from 'int' lvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}} /* => */ (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]}} /* => */ (void) int(ni);
(void) static_cast<intconst &>(ni); // expected-error {{static_cast from 'int' lvalue to 'const int &' lvalue should be written as const_cast [loplugin:redundantcast]}} /* => */ (void) const_cast<int const &>(ni);
(void) static_cast<intconst &&>(ni); // expected-error {{static_cast from 'int' lvalue to 'const int &&' xvalue should be written as const_cast [loplugin:redundantcast]}} /* => */ (void) const_cast<int const &&>(ni);
// non-class lvalue, const: intconst ci{};
(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]}} /* => */ (void) int(ci); // (void) static_cast<int &>(ci); // (void) static_cast<int &&>(ci);
(void) static_cast<intconst>(ci); // expected-error {{in static_cast from 'const int' lvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}} /* => */ (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]}} /* => */ (void) int(ci);
(void) static_cast<intconst &>(ci); // expected-error {{static_cast from 'const int' lvalue to 'const int &' lvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<intconst &&>(ci);
// non-class xvalue, non-const:
(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]}} /* => */ (void) int(nix()); // (void) static_cast<int &>(nix());
(void) static_cast<int &&>(nix()); // expected-error {{static_cast from 'int' xvalue to 'int &&' xvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<intconst>(nix()); // expected-error {{in static_cast from 'int' xvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}} /* => */ (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]}}
(void) static_cast<intconst &>(nix());
(void) static_cast<intconst &&>(nix()); // expected-error {{static_cast from 'int' xvalue to 'const int &&' xvalue should be written as const_cast [loplugin:redundantcast]}} /* => */ (void) const_cast<int const &&>(nix());
// non-class xvalue, const:
(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]}} /* => */ (void) int(cix()); // (void) static_cast<int &>(cix()); // (void) static_cast<int &&>(cix());
(void) static_cast<intconst>(cix()); // expected-error {{in static_cast from 'const int' xvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}} /* => */ (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]}} /* => */ (void) int(cix());
(void) static_cast<intconst &>(cix());
(void) static_cast<intconst &&>(cix()); // expected-error {{static_cast from 'const int' xvalue to 'const int &&' xvalue is redundant [loplugin:redundantcast]}}
// non-class prvalue, non-const:
(void) static_cast<int>(nir()); // expected-error {{static_cast from 'int' prvalue to 'int' prvalue is redundant [loplugin:redundantcast]}} // (void) static_cast<int &>(nir());
(void) static_cast<int &&>(nir());
(void) static_cast<intconst>(nir()); // expected-error {{in static_cast from 'int' prvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}} /* => */ (void) static_cast<int>(nir()); // expected-error {{static_cast from 'int' prvalue to 'int' prvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<intconst &>(nir()); // expected-error {{static_cast from 'int' prvalue to 'const int &' lvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<intconst &&>(nir());
// non-class prvalue, const:
(void) static_cast<int>(cir()); // expected-error {{static_cast from 'int' prvalue to 'int' prvalue is redundant [loplugin:redundantcast]}} // (void) static_cast<int &>(cir());
(void) static_cast<int &&>(cir());
(void) static_cast<intconst>(cir()); // expected-error {{in static_cast from 'int' prvalue to 'const int' prvalue, remove redundant top-level const qualifier [loplugin:redundantcast]}} /* => */ (void) static_cast<int>(cir()); // expected-error {{static_cast from 'int' prvalue to 'int' prvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<intconst &>(cir()); // expected-error {{static_cast from 'int' prvalue to 'const int &' lvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<intconst &&>(cir());
// class lvalue, non-const:
S ns{};
(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]}} /* => */ (void) S(ns);
(void) static_cast<S &>(ns); // expected-error {{static_cast from 'S' lvalue to 'S &' lvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<S &&>(ns);
(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]}} /* => */ using CS = const S; (void) CS(ns);
(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]}} /* => */ (void) const_cast<S const &>(ns);
(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]}} /* => */ (void) const_cast<S const &&>(ns);
// class lvalue, const:
S const cs{};
(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]}} /* => */ (void) S(cs); // (void) static_cast<S &>(cs); // (void) static_cast<S &&>(cs);
(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]}} /* => */ (void) CS(cs);
(void) static_cast<S const &>(cs); // expected-error {{static_cast from 'const S' lvalue to 'const S &' lvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<S const &&>(cs);
// class xvalue, non-const:
(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]}} /* => */ (void) S(nsx()); // (void) static_cast<S &>(nsx());
(void) static_cast<S &&>(nsx()); // expected-error {{static_cast from 'S' xvalue to 'S &&' xvalue is redundant [loplugin:redundantcast]}}
(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]}} /* => */ (void) CS(nsx());
(void) static_cast<S const &>(nsx());
(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]}} /* => */ (void) const_cast<S const &&>(nsx());
// class xvalue, const:
(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]}} /* => */ (void) S(csx()); // (void) static_cast<S &>(csx()); // (void) static_cast<S &&>(csx());
(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]}} /* => */ (void) CS(csx());
(void) static_cast<S const &>(csx());
(void) static_cast<S const &&>(csx()); // expected-error {{static_cast from 'const S' xvalue to 'const S &&' xvalue is redundant [loplugin:redundantcast]}}
// class prvalue, non-const:
(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]}} /* => */ (void) S(nsr()); // (void) static_cast<S &>(nsr());
(void) static_cast<S &&>(nsr());
(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]}} /* => */ (void) CS(nsr());
(void) static_cast<S const &>(nsr()); // expected-error {{static_cast from 'S' prvalue to 'const S &' lvalue is redundant [loplugin:redundantcast]}}
(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]}} /* => */ (void) const_cast<S const &&>(nsr());
// class prvalue, const:
(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]}} /* => */ (void) S(csr()); // (void) static_cast<S &>(csr()); // (void) static_cast<S &&>(csr());
(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]}} /* => */ (void) CS(csr());
(void) static_cast<S const &>(csr()); // expected-error {{static_cast from 'const S' prvalue to 'const S &' lvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<S const &&>(csr());
}
int & testReturnStaticCast(int && x) { returnstatic_cast<int &>(x); }
void testFunctionalCast() {
(void) int(nir()); // expected-error {{redundant functional cast from 'int' to 'int' [loplugin:redundantcast]}}
(void) S(nsr());
}
void testCStyleCast() {
Enum1 e = (Enum1)Enum1::X; // expected-error {{redundant cstyle cast from 'Enum1' to 'Enum1' [loplugin:redundantcast]}}
(void)e;
}
template<typename T> struct EnumItemInterface {
T GetValue() { returnstatic_cast<T>(0); }
}; class Enum1Item : public EnumItemInterface<Enum1> {
}; bool testCStyleCastOfTemplateMethodResult(Enum1Item* item) { return (Enum1)item->GetValue() == Enum1::X; // expected-error {{redundant cstyle cast from 'Enum1' to 'Enum1' [loplugin:redundantcast]}}
}
void testReinterpretCast() { int * p;
(void) reinterpret_cast<int *>(p); // expected-error {{redundant reinterpret_cast from 'int *' to 'int *' [loplugin:redundantcast]}}
}
void testReinterpretConstCast() { int n = 0;
(void) reinterpret_cast<std::size_t>((const_cast<intconst *>(&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]}}
}
void testSuspiciousReinterpretCast() {
D * p; // expected-error@+1 {{suspicious reinterpret_cast from derived 'D *' to base 'S *', maybe this was meant to be a static_cast [loplugin:redundantcast]}}
(void) reinterpret_cast<S *>(p);
(void) reinterpret_cast<sal_uIntPtr>(p); // expected no error
}
struct Overload { int overload(); long overload() const; void nonOverload();
};
void testOverloadResolution() {
(void) static_cast<void (*)(long)>(overload);
(void) static_cast<void (*)(long)>((overload));
(void) static_cast<void (*)(long)>(&overload);
(void) static_cast<void (*)(long)>((&overload));
(void) static_cast<void (*)(long)>(&((overload)));
(void) static_cast<void (*)()>(nonOverload); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<void (*)()>((nonOverload)); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<void (*)()>(&nonOverload); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<void (*)()>((&nonOverload)); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<void (*)()>(&((nonOverload))); // expected-error {{static_cast from 'void (*)()' prvalue to 'void (*)()' prvalue is redundant [loplugin:redundantcast]}}
(void) static_cast<long (Overload::*)() const>(&Overload::overload);
(void) static_cast<void (Overload::*)()>(&Overload::nonOverload); // expected-error {{static_cast from 'void (Overload::*)()' prvalue to 'void (Overload::*)()' prvalue is redundant [loplugin:redundantcast]}}
using OverloadFn = void (*)(long);
(void) OverloadFn(overload); using NonOverloadFn = void (*)();
(void) NonOverloadFn(nonOverload); // expected-error {{redundant functional cast from 'void (*)()' to 'NonOverloadFn' (aka 'void (*)()') [loplugin:redundantcast]}} using OverloadMemFn = long (Overload::*)() const;
(void) OverloadMemFn(&Overload::overload); using NonOverloadMemFn = void (Overload::*)();
(void) NonOverloadMemFn(&Overload::nonOverload); // expected-error {{redundant functional cast from 'void (Overload::*)()' to 'NonOverloadMemFn' (aka 'void (Overload::*)()') [loplugin:redundantcast]}}
};
void testIntermediaryStaticCast() { int n = 0;
n = static_cast<double>(n); // expected-error {{suspicious static_cast from 'int' to 'double', result is implicitly cast to 'int' [loplugin:redundantcast]}}
n = double(n); // expected-error {{suspicious functional cast from 'int' to 'double', result is implicitly cast to 'int' [loplugin:redundantcast]}} double d = 0.0;
d = static_cast<int>(d) + 1.0; // expected-error {{suspicious static_cast from 'double' to 'int', result is implicitly cast to 'double' [loplugin:redundantcast]}}
d = int(d) + 1.0; // expected-error {{suspicious functional cast from 'double' to 'int', result is implicitly cast to 'double' [loplugin:redundantcast]}}
};
void testArrayDecay() {
(void) static_cast<charconst *>(""); // expected-error-re {{redundant static_cast from 'const char{{ ?}}[1]' to 'const char *' [loplugin:redundantcast]}}
(void) reinterpret_cast<charconst *>(""); // expected-error-re {{redundant reinterpret_cast from 'const char{{ ?}}[1]' to 'const char *' [loplugin:redundantcast]}}
(void) reinterpret_cast<charconst *>(u8"");
}
void testNew() { class A {}; class B : public A {};
A* p = static_cast<A*>(new B); // expected-error {{redundant static_cast from 'B *' to 'A *' [loplugin:redundantcast]}}
(void)p; // no warning expected for resolving-ambiguity cast class C : public A {}; class D : public B, public C {};
p = static_cast<B*>(new D); // no warning expected for down-cast auto p2 = static_cast<B*>(p);
(void)p2;
}
using F = void (*)(); auto testNullFunctionPointer(int i, F p) { switch (i) { case 0: returnstatic_cast<F>(nullptr); case 1: return F(nullptr); default: return p;
}
}
void testSalIntTypes() {
sal_Int16 const n = 0;
(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]}}
(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]}}
(void) static_cast<short>(n); // doesn't warn, even if 'sal_Int16' is 'short' using Other = sal_Int16;
(void) static_cast<Other>(n); // doesn't warn either
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.