summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel <noel.grandin@collabora.co.uk>2021-02-02 09:41:52 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-02-02 12:24:00 +0100
commit068d4108e5ae41ca5bc2bcf22277e6235c6bdd0b (patch)
tree4139d3418c7c72d5126f64e59e192cac3e74c7ee /compilerplugins
parente763e13873adfe3c6abfa4c2dfd3ac3847e2d494 (diff)
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 <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/redundantcast.cxx37
-rw-r--r--compilerplugins/clang/test/redundantcast.cxx5
2 files changed, 35 insertions, 7 deletions
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<S2 *>(s1);
- (void) dynamic_cast<S1 *>(s2);
+ (void) dynamic_cast<S1 *>(s2); // expected-error {{redundant dynamic upcast from 'S2 *' to 'S1 *' [loplugin:redundantcast]}}
(void) dynamic_cast<S2 *>(s2); // expected-error {{redundant dynamic cast from 'S2 *' to 'S2 *' [loplugin:redundantcast]}}
(void) dynamic_cast<S3 *>(s2);
+ (void) dynamic_cast<const S2 *>(s2); // expected-error {{redundant dynamic cast from 'S2 *' to 'const S2 *' [loplugin:redundantcast]}}
+ (void) dynamic_cast<S1 *>(s3); // expected-error {{redundant dynamic upcast from 'S3 *' to 'S1 *' [loplugin:redundantcast]}}
}
void overload(int);