From 068d4108e5ae41ca5bc2bcf22277e6235c6bdd0b Mon Sep 17 00:00:00 2001 From: Noel Date: Tue, 2 Feb 2021 09:41:52 +0200 Subject: loplugin:redundantcast catch more dynamic_cast Change-Id: Ia28e58217cefa306567b53688d851fa210b7821c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110287 Tested-by: Jenkins Reviewed-by: Noel Grandin --- compilerplugins/clang/redundantcast.cxx | 37 +++++++++++++++++++++++----- compilerplugins/clang/test/redundantcast.cxx | 5 +++- 2 files changed, 35 insertions(+), 7 deletions(-) (limited to 'compilerplugins/clang') diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index bdac3f3bcc56..afc1cb414681 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -800,16 +800,41 @@ bool RedundantCast::VisitCXXDynamicCastExpr(CXXDynamicCastExpr const * expr) { if (ignoreLocation(expr)) { return true; } - // so far this only deals with dynamic casting from T to T auto const sub = compat::getSubExprAsWritten(expr); auto const t1 = expr->getTypeAsWritten(); auto const t2 = sub->getType(); - if (t1.getCanonicalType() != t2.getCanonicalType()) + QualType qt1 = t1.getCanonicalType(); + QualType qt2 = t2.getCanonicalType(); + if (qt1 == qt2) + { + report( + DiagnosticsEngine::Warning, + "redundant dynamic cast from %0 to %1", expr->getExprLoc()) + << t2 << t1 << expr->getSourceRange(); return true; - report( - DiagnosticsEngine::Warning, - "redundant dynamic cast from %0 to %1", expr->getExprLoc()) - << t2 << t1 << expr->getSourceRange(); + } + if (qt1->isPointerType() && qt2->isPointerType()) + { + // casting from 'T*' to 'const T*' is redundant, so compare without the qualifiers + qt1 = qt1->getPointeeType().getUnqualifiedType(); + qt2 = qt2->getPointeeType().getUnqualifiedType(); + if (qt1 == qt2) + { + report( + DiagnosticsEngine::Warning, + "redundant dynamic cast from %0 to %1", expr->getExprLoc()) + << t2 << t1 << expr->getSourceRange(); + return true; + } + if (qt1->getAsCXXRecordDecl() && qt2->getAsCXXRecordDecl()->isDerivedFrom(qt1->getAsCXXRecordDecl())) + { + report( + DiagnosticsEngine::Warning, + "redundant dynamic upcast from %0 to %1", expr->getExprLoc()) + << t2 << t1 << expr->getSourceRange(); + return true; + } + } return true; } diff --git a/compilerplugins/clang/test/redundantcast.cxx b/compilerplugins/clang/test/redundantcast.cxx index 03ce47796d65..97f4e6f73777 100644 --- a/compilerplugins/clang/test/redundantcast.cxx +++ b/compilerplugins/clang/test/redundantcast.cxx @@ -340,11 +340,14 @@ void testDynamicCast() { S1 * s1 = nullptr; S2 * s2 = nullptr; + S3 * s3 = nullptr; (void) dynamic_cast(s1); - (void) dynamic_cast(s2); + (void) dynamic_cast(s2); // expected-error {{redundant dynamic upcast from 'S2 *' to 'S1 *' [loplugin:redundantcast]}} (void) dynamic_cast(s2); // expected-error {{redundant dynamic cast from 'S2 *' to 'S2 *' [loplugin:redundantcast]}} (void) dynamic_cast(s2); + (void) dynamic_cast(s2); // expected-error {{redundant dynamic cast from 'S2 *' to 'const S2 *' [loplugin:redundantcast]}} + (void) dynamic_cast(s3); // expected-error {{redundant dynamic upcast from 'S3 *' to 'S1 *' [loplugin:redundantcast]}} } void overload(int); -- cgit