diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-08-27 11:06:41 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-08-27 18:42:13 +0200 |
commit | 9e0b3423f21c23a8ef2fe749ea7dd7c1194c2f9a (patch) | |
tree | 26f2674f88359c5e6c3e1d0f888c7b31836c36ee /compilerplugins/clang/redundantcast.cxx | |
parent | use SdrCircKind enum more widely (diff) | |
download | core-9e0b3423f21c23a8ef2fe749ea7dd7c1194c2f9a.tar.gz core-9e0b3423f21c23a8ef2fe749ea7dd7c1194c2f9a.zip |
loplugin:referencecasting find more redundant static_cast
Change-Id: I3a51812bbd3fcdc6b11e47cb12962f0d4fa7a2ae
Reviewed-on: https://gerrit.libreoffice.org/78191
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins/clang/redundantcast.cxx')
-rw-r--r-- | compilerplugins/clang/redundantcast.cxx | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index 3d9ff97b473b..d4e76846cbfa 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -28,6 +28,7 @@ #include "check.hxx" #include "compat.hxx" #include "plugin.hxx" +#include <iostream> namespace { @@ -136,8 +137,12 @@ public: bool VisitBinNE(BinaryOperator const * expr) { return visitBinOp(expr); } + bool VisitBinAssign(BinaryOperator const * binaryOperator); + bool VisitVarDecl(VarDecl const * varDecl); + private: bool visitBinOp(BinaryOperator const * expr); + void visitAssign(QualType lhs, Expr const * rhs); bool isOverloadedFunction(FunctionDecl const * decl); }; @@ -334,6 +339,55 @@ bool RedundantCast::VisitCStyleCastExpr(CStyleCastExpr const * expr) { return true; } +bool RedundantCast::VisitBinAssign(BinaryOperator const * binaryOperator) { + if (ignoreLocation(binaryOperator)) { + return true; + } + visitAssign(binaryOperator->getLHS()->getType(), binaryOperator->getRHS()); + return true; +} + +bool RedundantCast::VisitVarDecl(VarDecl const * varDecl) { + if (ignoreLocation(varDecl)) { + return true; + } + if (!varDecl->getInit()) + return true; + visitAssign(varDecl->getType(), varDecl->getInit()); + return true; +} + +void RedundantCast::visitAssign(QualType t1, Expr const * rhs) +{ + auto staticCastExpr = dyn_cast<CXXStaticCastExpr>(rhs->IgnoreImplicit()); + if (!staticCastExpr) + return; + + auto const t2 = staticCastExpr->getSubExpr()->IgnoreImplicit()->getType(); + + // if there is more than one copy of the LHS, this cast is resolving ambiguity + bool foundOne = false; + if (t1->isRecordType()) + { + foundOne = loplugin::derivedFromCount(t2, t1) == 1; + } + else + { + auto pointee1 = t1->getPointeeCXXRecordDecl(); + auto pointee2 = t2->getPointeeCXXRecordDecl(); + if (pointee1 && pointee2) + foundOne = loplugin::derivedFromCount(pointee2, pointee1) == 1; + } + + if (foundOne) + { + report( + DiagnosticsEngine::Warning, "redundant static_cast from %0 to %1", + staticCastExpr->getExprLoc()) + << t2 << t1 << staticCastExpr->getSourceRange(); + } +} + bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) { if (ignoreLocation(expr)) { return true; |