diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2019-11-04 15:58:29 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2019-11-04 17:20:28 +0100 |
commit | 75bbbfc6bd94246c75c6d0f0e0da5d55b41009b7 (patch) | |
tree | e38aeebf098a4eee9334bec48160d664e7309fca /compilerplugins | |
parent | 074cab391c20be872a4b5d14a342eda5c541b6fd (diff) |
loplugin:redundantcast: Don't warn about cast from nullptr_t to function ptr
See comments at <https://gerrit.libreoffice.org/#/c/81958/> "Only initialize
function pointer once" for a case where such a false warning caused trouble (in
a lambda with deduced return type and multiple return statements).
Change-Id: I64b0b8c45bd3d2a6075e336c361ec778fa0da481
Reviewed-on: https://gerrit.libreoffice.org/82034
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/redundantcast.cxx | 17 | ||||
-rw-r--r-- | compilerplugins/clang/test/redundantcast.cxx | 12 |
2 files changed, 26 insertions, 3 deletions
diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index d4e76846cbfa..1f7765b8978d 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -78,6 +78,17 @@ AlgebraicType algebraicType(clang::Type const & type) { } } +// Do not look through FunctionToPointerDecay, but through e.g. NullToPointer: +Expr const * stopAtFunctionPointerDecay(ExplicitCastExpr const * expr) { + auto const e1 = expr->getSubExpr(); + if (auto const e2 = dyn_cast<ImplicitCastExpr>(e1)) { + if (e2->getCastKind() != CK_FunctionToPointerDecay) { + return e2->getSubExpr(); + } + } + return e1; +} + class RedundantCast: public loplugin::FilteringRewritePlugin<RedundantCast> { @@ -394,7 +405,7 @@ bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) { } auto const t2 = expr->getTypeAsWritten(); bool const fnptr = t2->isFunctionPointerType() || t2->isMemberFunctionPointerType(); - auto const sub = fnptr ? expr->getSubExpr() : compat::getSubExprAsWritten(expr); + auto const sub = fnptr ? stopAtFunctionPointerDecay(expr) : compat::getSubExprAsWritten(expr); auto const t1 = sub->getType(); auto const nonClassObjectType = t2->isObjectType() && !(t2->isRecordType() || t2->isArrayType()); @@ -722,8 +733,8 @@ bool RedundantCast::VisitCXXFunctionalCastExpr(CXXFunctionalCastExpr const * exp // temporary): 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() + auto const sub = fnptr ? stopAtFunctionPointerDecay(expr) : compat::getSubExprAsWritten(expr); + if ((sub->getValueKind() != VK_RValue && !fnptr) || expr->getType()->isRecordType() || isa<InitListExpr>(sub) || isa<CXXStdInitializerListExpr>(sub)) { return true; diff --git a/compilerplugins/clang/test/redundantcast.cxx b/compilerplugins/clang/test/redundantcast.cxx index a876fae6e4b3..2ffd8f93c96f 100644 --- a/compilerplugins/clang/test/redundantcast.cxx +++ b/compilerplugins/clang/test/redundantcast.cxx @@ -406,6 +406,18 @@ void testNew() { (void)p2; } +using F = void (*)(); +auto testNullFunctionPointer(int i, F p) { + switch (i) { + case 0: + return static_cast<F>(nullptr); + case 1: + return F(nullptr); + default: + return p; + } +} + int main() { testConstCast(); testStaticCast(); |