diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-09-07 14:28:59 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-09-11 15:33:28 +0200 |
commit | 81fd3bb4d76a0e57a4e8464cb1c5813115ea28f3 (patch) | |
tree | 35f9c68537045403fe9deb514c7cc8b0672f4442 /compilerplugins | |
parent | 06f99cd5520fa431ffb74ca5dd4691e892715657 (diff) |
loplugin:redundantfcast check for std::function cast
noticed by mike kaganski
Change-Id: I210f6d2655edde74d9256c6147b7d15a88180196
Reviewed-on: https://gerrit.libreoffice.org/78743
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/redundantfcast.cxx | 56 | ||||
-rw-r--r-- | compilerplugins/clang/test/redundantfcast.cxx | 24 |
2 files changed, 57 insertions, 23 deletions
diff --git a/compilerplugins/clang/redundantfcast.cxx b/compilerplugins/clang/redundantfcast.cxx index a53c42d73add..8879a386d621 100644 --- a/compilerplugins/clang/redundantfcast.cxx +++ b/compilerplugins/clang/redundantfcast.cxx @@ -13,6 +13,7 @@ #include "plugin.hxx" #include <iostream> #include <fstream> +#include <unordered_set> namespace { @@ -53,9 +54,10 @@ public: { return true; } - report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", - cxxFunctionalCastExpr->getExprLoc()) - << t2 << t1 << cxxFunctionalCastExpr->getSourceRange(); + if (m_Seen.insert(cxxFunctionalCastExpr->getExprLoc()).second) + report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", + cxxFunctionalCastExpr->getExprLoc()) + << t2 << t1 << cxxFunctionalCastExpr->getSourceRange(); return true; } @@ -103,11 +105,14 @@ public: if (t1.getCanonicalType().getTypePtr() != paramClassOrStructType) continue; - report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", - arg->getExprLoc()) - << t2 << t1 << arg->getSourceRange(); - report(DiagnosticsEngine::Note, "in call to method here", param->getLocation()) - << param->getSourceRange(); + if (m_Seen.insert(arg->getExprLoc()).second) + { + report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", + arg->getExprLoc()) + << t2 << t1 << arg->getSourceRange(); + report(DiagnosticsEngine::Note, "in call to method here", param->getLocation()) + << param->getSourceRange(); + } } return true; } @@ -146,15 +151,28 @@ public: if (t1.getCanonicalType().getTypePtr() != paramClassOrStructType) continue; - report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", - arg->getExprLoc()) - << t2 << t1 << arg->getSourceRange(); - report(DiagnosticsEngine::Note, "in call to method here", param->getLocation()) - << param->getSourceRange(); + if (m_Seen.insert(arg->getExprLoc()).second) + { + report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", + arg->getExprLoc()) + << t2 << t1 << arg->getSourceRange(); + report(DiagnosticsEngine::Note, "in call to method here", param->getLocation()) + << param->getSourceRange(); + } } return true; } + // Find redundant cast to std::function, where clang reports + // two different types for the inner and outer + static bool isRedundantStdFunctionCast(CXXFunctionalCastExpr const* expr) + { + auto cxxConstruct = dyn_cast<CXXConstructExpr>(compat::IgnoreImplicit(expr->getSubExpr())); + if (!cxxConstruct) + return false; + return isa<LambdaExpr>(cxxConstruct->getArg(0)); + } + bool VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const* expr) { if (ignoreLocation(expr)) @@ -166,7 +184,8 @@ public: return true; auto const t1 = expr->getTypeAsWritten(); auto const t2 = compat::getSubExprAsWritten(expr)->getType(); - if (t1.getCanonicalType().getTypePtr() != t2.getCanonicalType().getTypePtr()) + if (!(t1.getCanonicalType().getTypePtr() == t2.getCanonicalType().getTypePtr() + || isRedundantStdFunctionCast(expr))) { return true; } @@ -191,9 +210,10 @@ public: if (tc.Typedef("sal_Int32").GlobalNamespace()) return true; - report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", - expr->getExprLoc()) - << t2 << t1 << expr->getSourceRange(); + if (m_Seen.insert(expr->getExprLoc()).second) + report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1", + expr->getExprLoc()) + << t2 << t1 << expr->getSourceRange(); //getParentStmt(expr)->dump(); return true; } @@ -218,6 +238,8 @@ public: if (preRun()) TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } + + std::unordered_set<SourceLocation> m_Seen; }; static loplugin::Plugin::Registration<RedundantFCast> redundantfcast("redundantfcast"); diff --git a/compilerplugins/clang/test/redundantfcast.cxx b/compilerplugins/clang/test/redundantfcast.cxx index 13e09b5e05b6..9b377c97d395 100644 --- a/compilerplugins/clang/test/redundantfcast.cxx +++ b/compilerplugins/clang/test/redundantfcast.cxx @@ -9,11 +9,12 @@ #include "sal/config.h" -#include <memory> - #include "rtl/ustring.hxx" #include "tools/color.hxx" +#include <functional> +#include <memory> + void method1(OUString const&); // expected-note {{in call to method here [loplugin:redundantfcast]}} struct Foo @@ -56,7 +57,6 @@ int main() OUString s1; method1(OUString( s1)); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantfcast]}} - // expected-error@-2 {{redundant functional cast from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantfcast]}} OUString s2; s2 = OUString( s1); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantfcast]}} @@ -68,11 +68,11 @@ int main() Foo foo(1); func1(Foo( - foo)); // expected-error@-1 {{redundant functional cast from 'Foo' to 'Foo' [loplugin:redundantfcast]}} expected-error@-1 {{redundant functional cast from 'Foo' to 'Foo' [loplugin:redundantfcast]}} + foo)); // expected-error@-1 {{redundant functional cast from 'Foo' to 'Foo' [loplugin:redundantfcast]}} const tools::Polygon aPolygon; ImplWritePolyPolygonRecord(tools::PolyPolygon(tools::Polygon( - aPolygon))); // expected-error@-1 {{redundant functional cast from 'const tools::Polygon' to 'tools::Polygon' [loplugin:redundantfcast]}} expected-error@-1 {{redundant functional cast from 'const tools::Polygon' to 'tools::Polygon' [loplugin:redundantfcast]}} + aPolygon))); // expected-error@-1 {{redundant functional cast from 'const tools::Polygon' to 'tools::Polygon' [loplugin:redundantfcast]}} } class Class1 @@ -81,7 +81,19 @@ class Class1 Foo func2() { return Foo( - foo); // expected-error@-1 {{redundant functional cast from 'Foo' to 'Foo' [loplugin:redundantfcast]}} expected-error@-1 {{redundant functional cast from 'Foo' to 'Foo' [loplugin:redundantfcast]}} + foo); // expected-error@-1 {{redundant functional cast from 'Foo' to 'Foo' [loplugin:redundantfcast]}} } }; + +// casting of lambdas +namespace test5 +{ +void f1(std::function<void()> x); +void f2() +{ + // expected-error-re@+1 {{redundant functional cast {{.+}} [loplugin:redundantfcast]}} + f1(std::function([&]() {})); +} +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |