diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2017-06-02 13:31:37 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2017-06-02 13:31:37 +0200 |
commit | 95645cbf0a220c338600130bdeca49743b252972 (patch) | |
tree | 9207b66ed98ea8f24573b6e1214d642314d68ad8 /compilerplugins | |
parent | ff77fdbe29f0cf93f93d6e75ba5ca101e2e321a5 (diff) |
Improved loplugin:redundantcast const_cast handling
Change-Id: I4c24ff5d9d5e74bef2a4040c6308c504282af55d
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/redundantcast.cxx | 20 | ||||
-rw-r--r-- | compilerplugins/clang/test/redundantcast.cxx | 112 |
2 files changed, 119 insertions, 13 deletions
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index 6bc97e5351a3..6d740ddca883 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -37,9 +37,12 @@ bool isVoidPointer(QualType type) { } bool isRedundantConstCast(CXXConstCastExpr const * expr) { - return expr->getTypeAsWritten().getCanonicalType().getTypePtr() - == (expr->getSubExprAsWritten()->getType().getCanonicalType() - .getTypePtr()); + auto const sub = compat::getSubExprAsWritten(expr); + return + (expr->getType().getCanonicalType() + == sub->getType().getCanonicalType()) + && (expr->getValueKind() != VK_XValue + || sub->getValueKind() == VK_XValue); } bool isArithmeticOp(Expr const * expr) { @@ -511,11 +514,14 @@ bool RedundantCast::VisitCXXConstCastExpr(CXXConstCastExpr const * expr) { return true; } if (isRedundantConstCast(expr)) { + auto const sub = compat::getSubExprAsWritten(expr); report( - DiagnosticsEngine::Warning, "redundant const_cast from %0 to %1", - expr->getExprLoc()) - << expr->getSubExprAsWritten()->getType() - << expr->getTypeAsWritten() << expr->getSourceRange(); + DiagnosticsEngine::Warning, + "redundant const_cast from %0 %1 to %2 %3", expr->getExprLoc()) + << sub->getType() << printExprValueKind(sub->getValueKind()) + << expr->getTypeAsWritten() + << printExprValueKind(expr->getValueKind()) + << expr->getSourceRange(); } return true; } diff --git a/compilerplugins/clang/test/redundantcast.cxx b/compilerplugins/clang/test/redundantcast.cxx index 6e5a8d42e589..1d2646a0f463 100644 --- a/compilerplugins/clang/test/redundantcast.cxx +++ b/compilerplugins/clang/test/redundantcast.cxx @@ -19,24 +19,124 @@ void testConstCast() { char const * p2; p1 = nullptr; p2 = ""; - f1(const_cast<char *>(p1)); // expected-error {{redundant const_cast from 'char *' to 'char *' [loplugin:redundantcast]}} - f1(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' to 'char *const' [loplugin:redundantcast]}} + 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 *' to 'char *' [loplugin:redundantcast]}} - f2(const_cast<char * const>(p1)); // expected-error {{redundant const_cast from 'char *' to 'char *const' [loplugin:redundantcast]}} + 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<char const *>(p1)); f2(const_cast<char const * 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<char const *>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'const char *' [loplugin:redundantcast]}} - f2(const_cast<char const * const>(p2)); // expected-error {{redundant const_cast from 'const char *' to 'const char *const' [loplugin:redundantcast]}} + f2(const_cast<char const *>(p2)); // expected-error {{redundant const_cast from 'const char *' lvalue to 'const char *' prvalue [loplugin:redundantcast]}} + f2(const_cast<char const * const>(p2)); // expected-error {{redundant const_cast from 'const char *' lvalue to 'const char *const' prvalue [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<int const &>(ni); + (void) const_cast<int const &&>(ni); + + // non-class lvalue, const: + int const 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<int const &>(ci); // expected-error {{redundant const_cast from 'const int' lvalue to 'const int &' lvalue [loplugin:redundantcast]}} + (void) const_cast<int const &&>(ci); + + // non-class xvalue, non-const: +// (void) const_cast<int>(nix()); +// (void) const_cast<int &>(nix()); + (void) const_cast<int &&>(nix()); // expected-error {{redundant const_cast from 'int' xvalue to 'int &&' xvalue [loplugin:redundantcast]}} +// (void) const_cast<int const>(nix()); +// (void) const_cast<int const &>(nix()); + (void) const_cast<int const &&>(nix()); + + // non-class xvalue, const: +// (void) const_cast<int>(cix()); +// (void) const_cast<int &>(cix()); + (void) const_cast<int &&>(cix()); +// (void) const_cast<int const>(cix()); +// (void) const_cast<int const &>(cix()); + (void) const_cast<int const &&>(cix()); // expected-error {{redundant const_cast from 'const int' xvalue to 'const int &&' xvalue [loplugin:redundantcast]}} + + // non-class prvalue, non-const: +// (void) const_cast<int>(nir()); +// (void) const_cast<int &>(nir()); +// (void) const_cast<int &&>(nir()); +// (void) const_cast<int const>(nir()); +// (void) const_cast<int const &>(nir()); +// (void) const_cast<int const &&>(nir()); + + // non-class prvalue, const: +// (void) const_cast<int>(cir()); +// (void) const_cast<int &>(cir()); +// (void) const_cast<int &&>(cir()); +// (void) const_cast<int const>(cir()); +// (void) const_cast<int const &>(cir()); +// (void) const_cast<int const &&>(cir()); + + // class lvalue, non-const: + S ns{}; +// (void) const_cast<S>(ns); + (void) const_cast<S &>(ns); // expected-error {{redundant const_cast from 'S' lvalue to 'S &' lvalue [loplugin:redundantcast]}} + (void) const_cast<S &&>(ns); +// (void) const_cast<S const>(ns); + (void) const_cast<S const &>(ns); + (void) const_cast<S const &&>(ns); + + // class lvalue, const: + S const cs{}; +// (void) const_cast<S>(cs); + (void) const_cast<S &>(cs); + (void) const_cast<S &&>(cs); +// (void) const_cast<S const>(cs); + (void) const_cast<S const &>(cs); // expected-error {{redundant const_cast from 'const S' lvalue to 'const S &' lvalue [loplugin:redundantcast]}} + (void) const_cast<S const &&>(cs); + + // class xvalue, non-const: +// (void) const_cast<S>(nsx()); +// (void) const_cast<S &>(nsx()); + (void) const_cast<S &&>(nsx()); // expected-error {{redundant const_cast from 'S' xvalue to 'S &&' xvalue [loplugin:redundantcast]}} +// (void) const_cast<S const>(nsx()); +// (void) const_cast<S const &>(nsx()); + (void) const_cast<S const &&>(nsx()); + + // class xvalue, const: +// (void) const_cast<S>(csx()); +// (void) const_cast<S &>(csx()); + (void) const_cast<S &&>(csx()); +// (void) const_cast<S const>(csx()); +// (void) const_cast<S const &>(csx()); + (void) const_cast<S const &&>(csx()); // expected-error {{redundant const_cast from 'const S' xvalue to 'const S &&' xvalue [loplugin:redundantcast]}} + + // class prvalue, non-const: +// (void) const_cast<S>(nsr()); +// (void) const_cast<S &>(nsr()); + (void) const_cast<S &&>(nsr()); +// (void) const_cast<S const>(nsr()); +// (void) const_cast<S const &>(nsr()); + (void) const_cast<S const &&>(nsr()); + + // class prvalue, const: +// (void) const_cast<S>(csr()); +// (void) const_cast<S &>(csr()); + (void) const_cast<S &&>(csr()); +// (void) const_cast<S const>(csr()); +// (void) const_cast<S const &>(csr()); + (void) const_cast<S const &&>(csr()); } void testStaticCast() { |