summaryrefslogtreecommitdiffstats
path: root/compilerplugins/clang/redundantfcast.cxx
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2018-03-09 13:59:52 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2018-03-12 07:37:24 +0100
commit2f5868c4309d49ad495e0763b5b57d1f7f98e377 (patch)
treeba498138c67436ce30b5d9585353c50a1c5020bf /compilerplugins/clang/redundantfcast.cxx
parentloplugin:unusedmethods (diff)
downloadcore-2f5868c4309d49ad495e0763b5b57d1f7f98e377.tar.gz
core-2f5868c4309d49ad495e0763b5b57d1f7f98e377.zip
loplugin:redundantfcast look for redundant copies in return statements
Change-Id: I5f416c865dfe1c36018784246a8007452eb42008 Reviewed-on: https://gerrit.libreoffice.org/50996 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins/clang/redundantfcast.cxx')
-rw-r--r--compilerplugins/clang/redundantfcast.cxx40
1 files changed, 40 insertions, 0 deletions
diff --git a/compilerplugins/clang/redundantfcast.cxx b/compilerplugins/clang/redundantfcast.cxx
index 811c6d48647c..89e5618e19da 100644
--- a/compilerplugins/clang/redundantfcast.cxx
+++ b/compilerplugins/clang/redundantfcast.cxx
@@ -21,6 +21,45 @@ public:
{
}
+ bool TraverseFunctionDecl(FunctionDecl* functionDecl)
+ {
+ auto prev = m_CurrentFunctionDecl;
+ m_CurrentFunctionDecl = functionDecl;
+ auto rv = RecursiveASTVisitor<RedundantFCast>::TraverseFunctionDecl(functionDecl);
+ m_CurrentFunctionDecl = prev;
+ return rv;
+ }
+
+ bool VisitReturnStmt(ReturnStmt const* returnStmt)
+ {
+ if (ignoreLocation(returnStmt))
+ return true;
+ Expr const* expr = returnStmt->getRetValue();
+ if (!expr)
+ return true;
+ if (auto exprWithCleanups = dyn_cast<ExprWithCleanups>(expr))
+ expr = exprWithCleanups->getSubExpr();
+ if (auto cxxConstructExpr = dyn_cast<CXXConstructExpr>(expr))
+ {
+ if (cxxConstructExpr->getNumArgs() != 1)
+ return true;
+ expr = cxxConstructExpr->getArg(0);
+ }
+ if (auto materializeTemporaryExpr = dyn_cast<MaterializeTemporaryExpr>(expr))
+ expr = materializeTemporaryExpr->GetTemporaryExpr();
+ auto cxxFunctionalCastExpr = dyn_cast<CXXFunctionalCastExpr>(expr);
+ if (!cxxFunctionalCastExpr)
+ return true;
+ auto const t1 = cxxFunctionalCastExpr->getTypeAsWritten();
+ auto const t2 = compat::getSubExprAsWritten(cxxFunctionalCastExpr)->getType();
+ if (t1.getCanonicalType().getTypePtr() != t2.getCanonicalType().getTypePtr())
+ return true;
+ report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1",
+ cxxFunctionalCastExpr->getExprLoc())
+ << t2 << t1 << cxxFunctionalCastExpr->getSourceRange();
+ return true;
+ }
+
/* Check for the creation of unnecessary temporaries when calling a method that takes a param by const & */
bool VisitCallExpr(CallExpr const* callExpr)
{
@@ -104,6 +143,7 @@ private:
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
}
+ FunctionDecl const* m_CurrentFunctionDecl;
};
static loplugin::Plugin::Registration<RedundantFCast> reg("redundantfcast");