diff options
Diffstat (limited to 'compilerplugins/clang/redundantcast.cxx')
-rw-r--r-- | compilerplugins/clang/redundantcast.cxx | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index ee731e2938fc..3abf66a853b3 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -156,6 +156,48 @@ bool RedundantCast::VisitImplicitCastExpr(const ImplicitCastExpr * expr) { } } break; + case CK_DerivedToBase: + case CK_UncheckedDerivedToBase: + if (expr->getType()->isPointerType()) { + Expr const * e = expr->getSubExpr()->IgnoreParenImpCasts(); + while (isa<CXXConstCastExpr>(e)) { + auto cc = dyn_cast<CXXConstCastExpr>(e); + if (expr->getType()->getAs<PointerType>()->getPointeeType() + .isAtLeastAsQualifiedAs( + cc->getSubExpr()->getType() + ->getAs<PointerType>()->getPointeeType())) + { + report( + DiagnosticsEngine::Warning, + ("redundant const_cast from %0 to %1, result is" + " ultimately implictly cast to %2"), + cc->getExprLoc()) + << cc->getSubExprAsWritten()->getType() << cc->getType() + << expr->getType() << expr->getSourceRange(); + } + e = cc->getSubExpr()->IgnoreParenImpCasts(); + } + } else if (expr->getType()->isReferenceType()) { + Expr const * e = expr->getSubExpr()->IgnoreParenImpCasts(); + while (isa<CXXConstCastExpr>(e)) { + auto cc = dyn_cast<CXXConstCastExpr>(e); + if (expr->getType()->getAs<ReferenceType>()->getPointeeType() + .isAtLeastAsQualifiedAs( + cc->getSubExpr()->getType() + ->getAs<ReferenceType>()->getPointeeType())) + { + report( + DiagnosticsEngine::Warning, + ("redundant const_cast from %0 to %1, result is" + " ultimately implictly cast to %2"), + cc->getExprLoc()) + << cc->getSubExprAsWritten()->getType() << cc->getType() + << expr->getType() << expr->getSourceRange(); + } + e = cc->getSubExpr()->IgnoreParenImpCasts(); + } + } + break; default: break; } |