diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index d390a7e15ccc..3d9ff97b473b 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -358,6 +358,28 @@ bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) { << expr->getSourceRange(); return true; } + if (auto const impl = dyn_cast(expr->getSubExpr())) { + if (impl->getCastKind() == CK_ArrayToPointerDecay && impl->getType() == t2) + //TODO: instead of exact QualType match, allow some variation? + { + auto const fn = handler.getMainFileName(); + if (!(loplugin::isSamePathname( + fn, SRCDIR "/sal/qa/rtl/strings/test_ostring_concat.cxx") + || loplugin::isSamePathname( + fn, SRCDIR "/sal/qa/rtl/strings/test_ostring_stringliterals.cxx") + || loplugin::isSamePathname( + fn, SRCDIR "/sal/qa/rtl/strings/test_oustring_concat.cxx") + || loplugin::isSamePathname( + fn, SRCDIR "/sal/qa/rtl/strings/test_oustring_stringliterals.cxx"))) + { + report( + DiagnosticsEngine::Warning, "redundant static_cast from %0 to %1", + expr->getExprLoc()) + << expr->getSubExprAsWritten()->getType() << t2 << expr->getSourceRange(); + } + return true; + } + } auto const t3 = expr->getType(); auto const c1 = t1.getCanonicalType(); auto const c3 = t3.getCanonicalType(); @@ -471,6 +493,30 @@ bool RedundantCast::VisitCXXReinterpretCastExpr( if (ignoreLocation(expr)) { return true; } + if (auto const sub = dyn_cast(expr->getSubExpr())) { + if (sub->getCastKind() == CK_ArrayToPointerDecay && sub->getType() == expr->getType()) + //TODO: instead of exact QualType match, allow some variation? + { + if (loplugin::TypeCheck(sub->getType()).Pointer().Const().Char()) { + if (auto const lit = dyn_cast(expr->getSubExprAsWritten())) { + if (lit->getKind() == clang::StringLiteral::UTF8) { + // Don't warn about + // + // redundant_cast(u8"...") + // + // in pre-C++2a code: + return true; + } + } + } + report( + DiagnosticsEngine::Warning, "redundant reinterpret_cast from %0 to %1", + expr->getExprLoc()) + << expr->getSubExprAsWritten()->getType() << expr->getTypeAsWritten() + << expr->getSourceRange(); + return true; + } + } if (expr->getSubExpr()->getType()->isVoidPointerType()) { auto t = expr->getType()->getAs(); if (t == nullptr || !t->getPointeeType()->isObjectType()) { diff --git a/compilerplugins/clang/test/redundantcast.cxx b/compilerplugins/clang/test/redundantcast.cxx index 3aae140d77f0..be34a57729c6 100644 --- a/compilerplugins/clang/test/redundantcast.cxx +++ b/compilerplugins/clang/test/redundantcast.cxx @@ -386,6 +386,12 @@ void testIntermediaryStaticCast() { d = int(d) + 1.0; // expected-error {{suspicious functional cast from 'double' to 'int', result is implicitly cast to 'double' [loplugin:redundantcast]}} }; +void testArrayDecay() { + (void) static_cast(""); // expected-error {{redundant static_cast from 'const char [1]' to 'const char *' [loplugin:redundantcast]}} + (void) reinterpret_cast(""); // expected-error {{redundant reinterpret_cast from 'const char [1]' to 'const char *' [loplugin:redundantcast]}} + (void) reinterpret_cast(u8""); +} + int main() { testConstCast(); testStaticCast(); @@ -395,6 +401,7 @@ int main() { testReinterpretConstCast(); testDynamicCast(); testIntermediaryStaticCast(); + testArrayDecay(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx index 59d121b70c28..eab50a288175 100644 --- a/vcl/workben/vcldemo.cxx +++ b/vcl/workben/vcldemo.cxx @@ -523,8 +523,8 @@ public: const char *mpString; } const aRuns[] = { #define SET(font,string) { font, reinterpret_cast(string) } - SET("sans", "a"), // logical font - no 'sans' font. - SET("opensymbol", "#$%"), // font fallback - $ is missing. + {"sans", "a"}, // logical font - no 'sans' font. + {"opensymbol", "#$%"}, // font fallback - $ is missing. SET("sans", pInvalid), // unicode invalid character // tdf#96266 - stacking diacritics SET("carlito", pDiacritic1),