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>
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
#include "plugin.hxx"
|
#include "plugin.hxx"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@@ -53,9 +54,10 @@ public:
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1",
|
if (m_Seen.insert(cxxFunctionalCastExpr->getExprLoc()).second)
|
||||||
cxxFunctionalCastExpr->getExprLoc())
|
report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1",
|
||||||
<< t2 << t1 << cxxFunctionalCastExpr->getSourceRange();
|
cxxFunctionalCastExpr->getExprLoc())
|
||||||
|
<< t2 << t1 << cxxFunctionalCastExpr->getSourceRange();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,11 +105,14 @@ public:
|
|||||||
if (t1.getCanonicalType().getTypePtr() != paramClassOrStructType)
|
if (t1.getCanonicalType().getTypePtr() != paramClassOrStructType)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1",
|
if (m_Seen.insert(arg->getExprLoc()).second)
|
||||||
arg->getExprLoc())
|
{
|
||||||
<< t2 << t1 << arg->getSourceRange();
|
report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1",
|
||||||
report(DiagnosticsEngine::Note, "in call to method here", param->getLocation())
|
arg->getExprLoc())
|
||||||
<< param->getSourceRange();
|
<< t2 << t1 << arg->getSourceRange();
|
||||||
|
report(DiagnosticsEngine::Note, "in call to method here", param->getLocation())
|
||||||
|
<< param->getSourceRange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -146,15 +151,28 @@ public:
|
|||||||
if (t1.getCanonicalType().getTypePtr() != paramClassOrStructType)
|
if (t1.getCanonicalType().getTypePtr() != paramClassOrStructType)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1",
|
if (m_Seen.insert(arg->getExprLoc()).second)
|
||||||
arg->getExprLoc())
|
{
|
||||||
<< t2 << t1 << arg->getSourceRange();
|
report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1",
|
||||||
report(DiagnosticsEngine::Note, "in call to method here", param->getLocation())
|
arg->getExprLoc())
|
||||||
<< param->getSourceRange();
|
<< t2 << t1 << arg->getSourceRange();
|
||||||
|
report(DiagnosticsEngine::Note, "in call to method here", param->getLocation())
|
||||||
|
<< param->getSourceRange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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)
|
bool VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const* expr)
|
||||||
{
|
{
|
||||||
if (ignoreLocation(expr))
|
if (ignoreLocation(expr))
|
||||||
@@ -166,7 +184,8 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
auto const t1 = expr->getTypeAsWritten();
|
auto const t1 = expr->getTypeAsWritten();
|
||||||
auto const t2 = compat::getSubExprAsWritten(expr)->getType();
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -191,9 +210,10 @@ public:
|
|||||||
if (tc.Typedef("sal_Int32").GlobalNamespace())
|
if (tc.Typedef("sal_Int32").GlobalNamespace())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1",
|
if (m_Seen.insert(expr->getExprLoc()).second)
|
||||||
expr->getExprLoc())
|
report(DiagnosticsEngine::Warning, "redundant functional cast from %0 to %1",
|
||||||
<< t2 << t1 << expr->getSourceRange();
|
expr->getExprLoc())
|
||||||
|
<< t2 << t1 << expr->getSourceRange();
|
||||||
//getParentStmt(expr)->dump();
|
//getParentStmt(expr)->dump();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -218,6 +238,8 @@ public:
|
|||||||
if (preRun())
|
if (preRun())
|
||||||
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
|
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unordered_set<SourceLocation> m_Seen;
|
||||||
};
|
};
|
||||||
|
|
||||||
static loplugin::Plugin::Registration<RedundantFCast> redundantfcast("redundantfcast");
|
static loplugin::Plugin::Registration<RedundantFCast> redundantfcast("redundantfcast");
|
||||||
|
@@ -9,11 +9,12 @@
|
|||||||
|
|
||||||
#include "sal/config.h"
|
#include "sal/config.h"
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "rtl/ustring.hxx"
|
#include "rtl/ustring.hxx"
|
||||||
#include "tools/color.hxx"
|
#include "tools/color.hxx"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
void method1(OUString const&); // expected-note {{in call to method here [loplugin:redundantfcast]}}
|
void method1(OUString const&); // expected-note {{in call to method here [loplugin:redundantfcast]}}
|
||||||
|
|
||||||
struct Foo
|
struct Foo
|
||||||
@@ -56,7 +57,6 @@ int main()
|
|||||||
OUString s1;
|
OUString s1;
|
||||||
method1(OUString(
|
method1(OUString(
|
||||||
s1)); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantfcast]}}
|
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;
|
OUString s2;
|
||||||
s2 = OUString(
|
s2 = OUString(
|
||||||
s1); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantfcast]}}
|
s1); // expected-error@-1 {{redundant functional cast from 'rtl::OUString' to 'rtl::OUString' [loplugin:redundantfcast]}}
|
||||||
@@ -68,11 +68,11 @@ int main()
|
|||||||
|
|
||||||
Foo foo(1);
|
Foo foo(1);
|
||||||
func1(Foo(
|
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;
|
const tools::Polygon aPolygon;
|
||||||
ImplWritePolyPolygonRecord(tools::PolyPolygon(tools::Polygon(
|
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
|
class Class1
|
||||||
@@ -81,7 +81,19 @@ class Class1
|
|||||||
Foo func2()
|
Foo func2()
|
||||||
{
|
{
|
||||||
return Foo(
|
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: */
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||||
|
@@ -413,7 +413,7 @@ Qt5Instance::createPicker(css::uno::Reference<css::uno::XComponentContext> const
|
|||||||
{
|
{
|
||||||
SolarMutexGuard g;
|
SolarMutexGuard g;
|
||||||
Qt5FilePicker* pPicker;
|
Qt5FilePicker* pPicker;
|
||||||
RunInMainThread(std::function([&, this]() { pPicker = createPicker(context, eMode); }));
|
RunInMainThread([&, this]() { pPicker = createPicker(context, eMode); });
|
||||||
assert(pPicker);
|
assert(pPicker);
|
||||||
return pPicker;
|
return pPicker;
|
||||||
}
|
}
|
||||||
|
@@ -43,9 +43,9 @@ KF5SalInstance::KF5SalInstance(std::unique_ptr<QApplication>& pQApp)
|
|||||||
SalFrame* KF5SalInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags nState)
|
SalFrame* KF5SalInstance::CreateFrame(SalFrame* pParent, SalFrameStyleFlags nState)
|
||||||
{
|
{
|
||||||
SalFrame* pRet(nullptr);
|
SalFrame* pRet(nullptr);
|
||||||
RunInMainThread(std::function([&pRet, pParent, nState]() {
|
RunInMainThread([&pRet, pParent, nState]() {
|
||||||
pRet = new KF5SalFrame(static_cast<KF5SalFrame*>(pParent), nState, true);
|
pRet = new KF5SalFrame(static_cast<KF5SalFrame*>(pParent), nState, true);
|
||||||
}));
|
});
|
||||||
assert(pRet);
|
assert(pRet);
|
||||||
return pRet;
|
return pRet;
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ KF5SalInstance::createPicker(css::uno::Reference<css::uno::XComponentContext> co
|
|||||||
{
|
{
|
||||||
SolarMutexGuard g;
|
SolarMutexGuard g;
|
||||||
Qt5FilePicker* pPicker;
|
Qt5FilePicker* pPicker;
|
||||||
RunInMainThread(std::function([&, this]() { pPicker = createPicker(context, eMode); }));
|
RunInMainThread([&, this]() { pPicker = createPicker(context, eMode); });
|
||||||
assert(pPicker);
|
assert(pPicker);
|
||||||
return pPicker;
|
return pPicker;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user