diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2017-06-03 07:54:55 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2017-06-05 21:17:59 +0200 |
commit | 0f84a32f5b1dbc9f3751b4f8432283867932e155 (patch) | |
tree | de28a3c35ec1bce988b69657c4521b1146cc399d /compilerplugins | |
parent | 8301695f8fd16338128261b1edbf60852f2d0a68 (diff) |
Improved loplugin:redundantcast, const/static_cast combinations
Change-Id: I3b24327835cd4e1842ee6e9b87ab06efa25a4bbf
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/redundantcast.cxx | 52 | ||||
-rw-r--r-- | compilerplugins/clang/test/redundantcast.cxx | 7 |
2 files changed, 58 insertions, 1 deletions
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index 4e79415c4850..2a66f8ff0704 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -513,8 +513,8 @@ bool RedundantCast::VisitCXXConstCastExpr(CXXConstCastExpr const * expr) { if (ignoreLocation(expr)) { return true; } + auto const sub = compat::getSubExprAsWritten(expr); if (isRedundantConstCast(expr)) { - auto const sub = compat::getSubExprAsWritten(expr); report( DiagnosticsEngine::Warning, "redundant const_cast from %0 %1 to %2 %3", expr->getExprLoc()) @@ -522,6 +522,56 @@ bool RedundantCast::VisitCXXConstCastExpr(CXXConstCastExpr const * expr) { << expr->getTypeAsWritten() << printExprValueKind(expr->getValueKind()) << expr->getSourceRange(); + return true; + } + if (auto const dce = dyn_cast<CXXStaticCastExpr>( + sub->IgnoreParenImpCasts())) + { + auto const sub2 = compat::getSubExprAsWritten(dce); + auto t1 = sub2->getType().getCanonicalType(); + auto isNullptr = t1->isNullPtrType(); + auto t2 = dce->getType().getCanonicalType(); + auto t3 = expr->getType().getCanonicalType(); + auto redundant = false; + for (;;) { + if ((t2.isConstQualified() + && (isNullptr || !t1.isConstQualified()) + && !t3.isConstQualified()) + || (t2.isVolatileQualified() + && (isNullptr || !t1.isVolatileQualified()) + && !t3.isVolatileQualified())) + { + redundant = true; + break; + } + if (!isNullptr) { + auto const p1 = t1->getAs<clang::PointerType>(); + if (p1 == nullptr) { + break; + } + t1 = p1->getPointeeType(); + isNullptr = t1->isNullPtrType(); + } + auto const p2 = t2->getAs<clang::PointerType>(); + if (p2 == nullptr) { + break; + } + t2 = p2->getPointeeType(); + auto const p3 = t3->getAs<clang::PointerType>(); + if (p3 == nullptr) { + break; + } + t3 = p3->getPointeeType(); + } + if (redundant) { + report( + DiagnosticsEngine::Warning, + ("redundant static_cast/const_cast combination from %0 via %1" + " to %2"), + expr->getExprLoc()) + << sub2->getType() << dce->getTypeAsWritten() + << expr->getTypeAsWritten() << expr->getSourceRange(); + } } return true; } diff --git a/compilerplugins/clang/test/redundantcast.cxx b/compilerplugins/clang/test/redundantcast.cxx index 78624810fda9..9eda22a04b0f 100644 --- a/compilerplugins/clang/test/redundantcast.cxx +++ b/compilerplugins/clang/test/redundantcast.cxx @@ -12,6 +12,8 @@ void f1(char *) {} void f2(char const *) {} +struct D: S {}; + enum Enum1 { X }; void testConstCast() { @@ -32,6 +34,11 @@ void testConstCast() { 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]}} + void * vp = nullptr; + (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]}} + (void) const_cast<char *>(static_cast<char const *>(nullptr)); // expected-error {{redundant static_cast/const_cast combination from '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]}} |