diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-03-09 13:59:52 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-03-12 07:37:24 +0100 |
commit | 2f5868c4309d49ad495e0763b5b57d1f7f98e377 (patch) | |
tree | ba498138c67436ce30b5d9585353c50a1c5020bf /compilerplugins/clang | |
parent | cb34e6083cdc82333d64ad9224e0d25e895d1dae (diff) |
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')
-rw-r--r-- | compilerplugins/clang/redundantfcast.cxx | 40 | ||||
-rw-r--r-- | compilerplugins/clang/test/redundantfcast.cxx | 9 |
2 files changed, 49 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"); diff --git a/compilerplugins/clang/test/redundantfcast.cxx b/compilerplugins/clang/test/redundantfcast.cxx index 609b787347e1..da7e8be5a027 100644 --- a/compilerplugins/clang/test/redundantfcast.cxx +++ b/compilerplugins/clang/test/redundantfcast.cxx @@ -56,4 +56,13 @@ int main() foo)); // expected-error@-1 {{redundant functional cast from 'Foo' to 'Foo' [loplugin:redundantfcast]}} } +class Class1 +{ + Foo foo; + Foo func2() + { + return Foo( + foo); // expected-error@-1 {{redundant functional cast from 'Foo' to 'Foo' [loplugin:redundantfcast]}} + } +}; /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |