diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2017-12-05 11:37:59 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2017-12-05 18:11:15 +0100 |
commit | 306ddfb1b87d94a343e8e2b6b9270ca682f92ac3 (patch) | |
tree | ef46ec8bc63d3db71ebe17a571ec8f9787d6c814 /compilerplugins/clang/redundantcast.cxx | |
parent | Fix typo (diff) | |
download | core-306ddfb1b87d94a343e8e2b6b9270ca682f92ac3.tar.gz core-306ddfb1b87d94a343e8e2b6b9270ca682f92ac3.zip |
Replace deprecated std::mem_fun et al in reportdesign
(as std::mem_fun is gone by default at least from recent libc++ in C++17 mode)
Change-Id: Ib66134bd4072dfe0ce3bc36aa684cee710921235
Reviewed-on: https://gerrit.libreoffice.org/45868
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins/clang/redundantcast.cxx')
-rw-r--r-- | compilerplugins/clang/redundantcast.cxx | 63 |
1 files changed, 59 insertions, 4 deletions
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index bdf23d9094cf..2f905d355720 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -161,6 +161,7 @@ public: private: bool visitBinOp(BinaryOperator const * expr); bool isOkToRemoveArithmeticCast(QualType t1, QualType t2, const Expr* subExpr); + bool isOverloadedFunction(FunctionDecl const * decl); }; bool RedundantCast::VisitImplicitCastExpr(const ImplicitCastExpr * expr) { @@ -362,9 +363,10 @@ bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) { if (ignoreLocation(expr)) { return true; } - auto const sub = compat::getSubExprAsWritten(expr); - auto const t1 = sub->getType(); auto const t2 = expr->getTypeAsWritten(); + bool const fnptr = t2->isFunctionPointerType() || t2->isMemberFunctionPointerType(); + auto const sub = fnptr ? expr->getSubExpr() : compat::getSubExprAsWritten(expr); + auto const t1 = sub->getType(); auto const nonClassObjectType = t2->isObjectType() && !(t2->isRecordType() || t2->isArrayType()); if (nonClassObjectType && t2.hasLocalQualifiers()) { @@ -445,6 +447,23 @@ bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) { { return true; } + // Don't warn if a static_cast on a pointer to function or member function is used to + // disambiguate an overloaded function: + if (fnptr) { + auto e = sub->IgnoreParenImpCasts(); + if (auto const e1 = dyn_cast<UnaryOperator>(e)) { + if (e1->getOpcode() == UO_AddrOf) { + e = e1->getSubExpr()->IgnoreParenImpCasts(); + } + } + if (auto const e1 = dyn_cast<DeclRefExpr>(e)) { + if (auto const fdecl = dyn_cast<FunctionDecl>(e1->getDecl())) { + if (isOverloadedFunction(fdecl)) { + return true; + } + } + } + } // Suppress warnings from static_cast<bool> in C++ definition of assert in // <https://sourceware.org/git/?p=glibc.git;a=commit; // h=b5889d25e9bf944a89fdd7bcabf3b6c6f6bb6f7c> "assert: Support types @@ -625,7 +644,9 @@ bool RedundantCast::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const * exp // ), and only to cases where the sub-expression already is a prvalue of // non-class type (and thus the cast is unlikely to be meant to create a // temporary): - auto const sub = compat::getSubExprAsWritten(expr); + auto const t1 = expr->getTypeAsWritten(); + bool const fnptr = t1->isFunctionPointerType() || t1->isMemberFunctionPointerType(); + auto const sub = fnptr ? expr->getSubExpr() : compat::getSubExprAsWritten(expr); if (sub->getValueKind() != VK_RValue || expr->getType()->isRecordType() || isa<InitListExpr>(sub) || isa<CXXStdInitializerListExpr>(sub)) { @@ -643,6 +664,24 @@ bool RedundantCast::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const * exp } } + // Don't warn if a functional cast on a pointer to function or member function is used to + // disambiguate an overloaded function: + if (fnptr) { + auto e = sub->IgnoreParenImpCasts(); + if (auto const e1 = dyn_cast<UnaryOperator>(e)) { + if (e1->getOpcode() == UO_AddrOf) { + e = e1->getSubExpr()->IgnoreParenImpCasts(); + } + } + if (auto const e1 = dyn_cast<DeclRefExpr>(e)) { + if (auto const fdecl = dyn_cast<FunctionDecl>(e1->getDecl())) { + if (isOverloadedFunction(fdecl)) { + return true; + } + } + } + } + // See the commit message of d0e7d020fa405ab94f19916ec96fbd4611da0031 // "socket.c -> socket.cxx" for the reason to have // @@ -666,7 +705,6 @@ bool RedundantCast::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const * exp } } - auto const t1 = expr->getTypeAsWritten(); auto const t2 = sub->getType(); if (t1.getCanonicalType() != t2.getCanonicalType()) return true; @@ -766,6 +804,23 @@ bool RedundantCast::visitBinOp(BinaryOperator const * expr) { return true; } +bool RedundantCast::isOverloadedFunction(FunctionDecl const * decl) { + auto const ctx = decl->getDeclContext(); + if (!compat::isLookupContext(*ctx)) { + return false; + } + auto const canon = decl->getCanonicalDecl(); + auto const res = ctx->lookup(decl->getDeclName()); + for (auto d = res.begin(); d != res.end(); ++d) { + if (auto const f = dyn_cast<FunctionDecl>(*d)) { + if (f->getCanonicalDecl() != canon) { + return true; + } + } + } + return false; +} + loplugin::Plugin::Registration<RedundantCast> X("redundantcast", true); } |