summaryrefslogtreecommitdiffstats
path: root/compilerplugins/clang/redundantcast.cxx
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2019-08-27 11:06:41 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2019-08-27 18:42:13 +0200
commit9e0b3423f21c23a8ef2fe749ea7dd7c1194c2f9a (patch)
tree26f2674f88359c5e6c3e1d0f888c7b31836c36ee /compilerplugins/clang/redundantcast.cxx
parentuse SdrCircKind enum more widely (diff)
downloadcore-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.cxx54
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;