/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // Warn about certain redundant casts: // // * A reinterpret_cast(...) whose result is then implicitly cast to a void // pointer // // * A static_cast(e) where e is of void pointer type and whose result is // then implicitly cast to a void pointer // // * Various const_casts that are either not needed (like casting away constness // in a delete expression) or are implicitly cast back afterwards // // C-style casts are ignored because it makes this plugin simpler, and they // should eventually be eliminated via loplugin:cstylecast and/or // -Wold-style-cast. That implies that this plugin is only relevant for C++ // code. #include "clang/Sema/Sema.h" #include "compat.hxx" #include "plugin.hxx" namespace { bool isVoidPointer(QualType type) { return type->isPointerType() && type->getAs()->getPointeeType()->isVoidType(); } class RedundantCast: public RecursiveASTVisitor, public loplugin::RewritePlugin { public: explicit RedundantCast(InstantiationData const & data): RewritePlugin(data) {} virtual void run() override { if (compiler.getLangOpts().CPlusPlus) { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } } bool VisitImplicitCastExpr(ImplicitCastExpr const * expr); bool VisitCXXReinterpretCastExpr(CXXReinterpretCastExpr const * expr); bool VisitCXXConstCastExpr(CXXConstCastExpr const * expr); bool VisitCallExpr(CallExpr const * expr); bool VisitCXXDeleteExpr(CXXDeleteExpr const * expr); bool VisitBinSub(BinaryOperator const * expr) { return visitBinOp(expr); } bool VisitBinLT(BinaryOperator const * expr) { return visitBinOp(expr); } bool VisitBinGT(BinaryOperator const * expr) { return visitBinOp(expr); } bool VisitBinLE(BinaryOperator const * expr) { return visitBinOp(expr); } bool VisitBinGE(BinaryOperator const * expr) { return visitBinOp(expr); } bool VisitBinEQ(BinaryOperator const * expr) { return visitBinOp(expr); } bool VisitBinNE(BinaryOperator const * expr) { return visitBinOp(expr); } private: bool visitBinOp(BinaryOperator const * expr); }; bool RedundantCast::VisitImplicitCastExpr(const ImplicitCastExpr * expr) { if (ignoreLocation(expr)) { return true; } switch (expr->getCastKind()) { case CK_NoOp: if (expr->getType()->isPointerType() || expr->getType()->isObjectType()) { auto e = dyn_cast( expr->getSubExpr()->IgnoreParenImpCasts()); if (e != nullptr) { auto t1 = e->getSubExpr()->getType().getCanonicalType(); auto t2 = expr->getType().getCanonicalType(); bool ObjCLifetimeConversion; if (t1.getTypePtr() == t2.getTypePtr() || compiler.getSema().IsQualificationConversion( t1, t2, false, ObjCLifetimeConversion)) { report( DiagnosticsEngine::Warning, ("redundant const_cast from %0 to %1, result is" " implictly cast to %2"), e->getExprLoc()) << e->getSubExprAsWritten()->getType() << e->getType() << expr->getType() << expr->getSourceRange(); } } } break; case CK_BitCast: if (isVoidPointer(expr->getType()) && expr->getSubExpr()->getType()->isPointerType()) { Expr const * e = expr->getSubExpr()->IgnoreParenImpCasts(); while (isa(e)) { auto cc = dyn_cast(e); if (expr->getType()->getAs()->getPointeeType() .isAtLeastAsQualifiedAs( cc->getSubExpr()->getType() ->getAs()->getPointeeType())) { report( DiagnosticsEngine::Warning, ("redundant const_cast from %0 to %1, result is" " ultimately implictly cast to %2"), cc->getExprLoc()) << cc->getSubExprAsWritten()->getType() << cc->getType() << expr->getType() << expr->getSourceRange(); } e = cc->getSubExpr()->IgnoreParenImpCasts(); } if (isa(e)) { report( DiagnosticsEngine::Warning, ("redundant reinterpret_cast, result is implicitly cast to" " void pointer"), e->getExprLoc()) << e->getSourceRange(); } else if (isa(e) && isVoidPointer( dyn_cast(e)->getSubExpr() ->IgnoreParenImpCasts()->getType()) && !compat::isMacroBodyExpansion( compiler, e->getLocStart())) { report( DiagnosticsEngine::Warning, ("redundant static_cast from void pointer, result is" " implicitly cast to void pointer"), e->getExprLoc()) << e->getSourceRange(); } } break; case CK_DerivedToBase: case CK_UncheckedDerivedToBase: if (expr->getType()->isPointerType()) { Expr const * e = expr->getSubExpr()->IgnoreParenImpCasts(); while (isa(e)) { auto cc = dyn_cast(e); if (expr->getType()->getAs()->getPointeeType() .isAtLeastAsQualifiedAs( cc->getSubExpr()->getType() ->getAs()->getPointeeType())) { report( DiagnosticsEngine::Warning, ("redundant const_cast from %0 to %1, result is" " ultimately implictly cast to %2"), cc->getExprLoc()) << cc->getSubExprAsWritten()->getType() << cc->getType() << expr->getType() << expr->getSourceRange(); } e = cc->getSubExpr()->IgnoreParenImpCasts(); } } else if (expr->getType()->isReferenceType()) { Expr const * e = expr->getSubExpr()->IgnoreParenImpCasts(); while (isa(e)) { auto cc = dyn_cast(e); if (expr->getType()->getAs()->getPointeeType() .isAtLeastAsQualifiedAs( cc->getSubExpr()->getType() ->getAs()->getPointeeType())) { report( DiagnosticsEngine::Warning, ("redundant const_cast from %0 to %1, result is" " ultimately implictly cast to %2"), cc->getExprLoc()) << cc->getSubExprAsWritten()->getType() << cc->getType() << expr->getType() << expr->getSourceRange(); } e = cc->getSubExpr()->IgnoreParenImpCasts(); } } break; default: break; } return true; } bool RedundantCast::VisitCXXReinterpretCastExpr( CXXReinterpretCastExpr const * expr) { if (ignoreLocation(expr)) { return true; } if (expr->getSubExpr()->getType()->isVoidPointerType()) { auto t = expr->getType()->getAs(); if (t == nullptr || !t->getPointeeType()->isObjectType()) { return true; } if (rewriter != nullptr) { auto loc = expr->getLocStart(); while (compiler.getSourceManager().isMacroArgExpansion(loc)) { loc = compiler.getSourceManager().getImmediateMacroCallerLoc( loc); } if (compat::isMacroBodyExpansion(compiler, loc)) { auto loc2 = expr->getLocEnd(); while (compiler.getSourceManager().isMacroArgExpansion(loc2)) { loc2 = compiler.getSourceManager() .getImmediateMacroCallerLoc(loc2); } if (compat::isMacroBodyExpansion(compiler, loc2)) { //TODO: check loc, loc2 are in same macro body expansion loc = compiler.getSourceManager().getSpellingLoc(loc); } } auto s = compiler.getSourceManager().getCharacterData(loc); auto n = Lexer::MeasureTokenLength( loc, compiler.getSourceManager(), compiler.getLangOpts()); std::string tok(s, n); if (tok == "reinterpret_cast" && replaceText(loc, n, "static_cast")) { return true; } } report( DiagnosticsEngine::Warning, "reinterpret_cast from %0 to %1 can be simplified to static_cast", expr->getExprLoc()) << expr->getSubExprAsWritten()->getType() << expr->getType() << expr->getSourceRange(); } else if (expr->getType()->isVoidPointerType()) { auto t = expr->getSubExpr()->getType()->getAs(); if (t == nullptr || !t->getPointeeType()->isObjectType()) { return true; } report( DiagnosticsEngine::Warning, ("reinterpret_cast from %0 to %1 can be simplified to static_cast" " or an implicit conversion"), expr->getExprLoc()) << expr->getSubExprAsWritten()->getType() << expr->getType() << expr->getSourceRange(); } return true; } bool RedundantCast::VisitCXXConstCastExpr(CXXConstCastExpr const * expr) { if (ignoreLocation(expr)) { return true; } if (expr->getTypeAsWritten().getCanonicalType().getTypePtr() == (expr->getSubExprAsWritten()->getType().getCanonicalType() .getTypePtr())) { report( DiagnosticsEngine::Warning, "redundant const_cast from %0 to %1", expr->getExprLoc()) << expr->getSubExprAsWritten()->getType() << expr->getTypeAsWritten() << expr->getSourceRange(); } return true; } bool RedundantCast::VisitCallExpr(CallExpr const * expr) { if (ignoreLocation(expr)) { return true; } auto f = expr->getDirectCallee(); if (f == nullptr || !f->isVariadic() || expr->getNumArgs() <= f->getNumParams()) { return true; } for (auto i = f->getNumParams(); i != expr->getNumArgs(); ++i) { auto a = expr->getArg(i); if (a->getType()->isPointerType()) { auto e = dyn_cast(a->IgnoreParenImpCasts()); if (e != nullptr) { report( DiagnosticsEngine::Warning, "redundant const_cast of variadic function argument", e->getExprLoc()) << expr->getSourceRange(); } } } return true; } bool RedundantCast::VisitCXXDeleteExpr(CXXDeleteExpr const * expr) { if (ignoreLocation(expr)) { return true; } auto e = dyn_cast( expr->getArgument()->IgnoreParenImpCasts()); if (e != nullptr) { report( DiagnosticsEngine::Warning, "redundant const_cast in delete expression", e->getExprLoc()) << expr->getSourceRange(); } return true; } bool RedundantCast::visitBinOp(BinaryOperator const * expr) { if (ignoreLocation(expr)) { return true; } if (expr->getLHS()->getType()->isPointerType() && expr->getRHS()->getType()->isPointerType()) { auto e = dyn_cast( expr->getLHS()->IgnoreParenImpCasts()); if (e != nullptr) { report( DiagnosticsEngine::Warning, "redundant const_cast on lhs of pointer %select{comparison|subtraction}0 expression", e->getExprLoc()) << (expr->getOpcode() == BO_Sub) << expr->getSourceRange(); } e = dyn_cast( expr->getRHS()->IgnoreParenImpCasts()); if (e != nullptr) { report( DiagnosticsEngine::Warning, "redundant const_cast on rhs of pointer %select{comparison|subtraction}0 expression", e->getExprLoc()) << (expr->getOpcode() == BO_Sub) << expr->getSourceRange(); } } return true; } loplugin::Plugin::Registration X("redundantcast", true); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ re/cib_contract57d+hotfix'>feature/cib_contract57d+hotfix LibreOffice 核心代码仓库文档基金会
summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2019-05-03Use hasElements to check Sequence emptiness in sfx2..svxArkadiy Illarionov
Similar to clang-tidy readability-container-size-empty Change-Id: Icabd773f3b924d465b33e8581175f1fcf70c282e Reviewed-on: https://gerrit.libreoffice.org/71704 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2018-10-26tdf#42949 Fix IWYU warnings in include/unotools/*Gabor Kelemen
Found with bin/find-unneeded-includes Only removal proposals are dealt with here. Change-Id: I444c43b9d549977039f25bec2b5bf666c3e15e0e Reviewed-on: https://gerrit.libreoffice.org/62041 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
2018-01-11loplugin:useuniqueptr in svlNoel Grandin
Change-Id: I2fdb63517349474d90cb17ad2bd667f30840e83d Reviewed-on: https://gerrit.libreoffice.org/47727 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2017-12-22request installation of langpack via packagekitCaolán McNamara
if ui is set to track the locale automatically and the current locale has no match in installed resources but has a match in the list of languages that libreoffice was compiled to contain so e.g. de_AT locale shouldn't trigger the installation of anything if langpack-de is already installed and yue_HK shouldn't trigger install of anything cause that not supported (at time of writing) for libreoffice put Fedora/RHEL/Ubuntu naming schemes in here. I moved the lang code from svl to svtools so I could use the restart dialog to prompt to restart after the langpack is installed, but packagekit's blocking mode seems to be no longer blocking and control returns immediately which is a change since the last time I played with this stuff, so drop the restart thing for now. The lack of a blocking modal also makes the "run this on idle when there's a toplevel window up and running" a bit futile, but lets keep that for now anyway. caolanm->rene: I know you'd disable this anyway, so Debian is left out, there's also config key Office/Common/PackageKit/EnableLangpackInstallation to disable this too. Change-Id: Ice731be539850338ccdd8af87839e0b4d83f01e7 Reviewed-on: https://gerrit.libreoffice.org/46856 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
2017-10-23loplugin:includeform: svlStephan Bergmann
Change-Id: I769b091515d1e6b7d16652d11ff2b94a75584ad0
2017-09-19Clean up the code by using LOWORDStephan Bergmann
<https://msdn.microsoft.com/en-us/library/windows/desktop/ ms646296(v=vs.85).aspx> documents: "The low word contains a Language Identifier for the input language and the high word contains a device handle to the physical layout of the keyboard. Change-Id: I0b35e7a0f2bf5570dcf57cffe59ed2e2db361d2e
2017-09-18Use even more WIN32_LEAN_AND_MEANMike Kaganski
Change-Id: I538fe5b41156366e0e87b3a93e58a3947afd18f5 Reviewed-on: https://gerrit.libreoffice.org/42398 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
2017-04-26use strong_int for LanguageTypeNoel Grandin
Change-Id: If99a944f7032180355da291ad283b4cfcea4f448 Reviewed-on: https://gerrit.libreoffice.org/36629 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2017-01-10loplugin:unusedmethodsNoel Grandin
Change-Id: Ibe11923601760ded53a277c48631e4893606b2d6 Reviewed-on: https://gerrit.libreoffice.org/32875 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
2016-10-15clang-cl loplugin: svlStephan Bergmann
The DdeInternal::Cli/SrvCallback functions apparently had broken signatures for 64-bit Windows (32-bit DWORD vs. 64-bit ULONG_PTR parameters), but I assume that was actually harmless, as I think that, for Windows x86-64, those arguments are pushed on the stack right-to-left (regardless of CALLBACK), and they are the last arguments, and SrvCallback doesn't look at them at all, and CliCallback only looks at the lower 32-bit DWORD of the first one (nInfo1). Change-Id: Id77749dd2d29180e2d11b0ae2ad248ac1a7f1bdf Reviewed-on: https://gerrit.libreoffice.org/29848 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2016-09-28Resolves: tdf#96748 'Default Language' show current ui lang not new defaultCaolán McNamara
i.e. if you select it, then the General::UILocale is unset and a new default generated based on the L10N::UILocale and what langpacks are installed but what the entry string claims is "Default - Current Language", rather than "Default - The Language That Will Be Used", so split out the language selection code into a reusable bit and use that to get the name of the language which will be selected if this entry is used Change-Id: I13d901c9a47ef213aea86417501114d4231efae5
2016-02-17use consistent #define checks for the Windows platformNoel Grandin
stage 2 of replacing usage of various checks for the windows platform with the compiler-defined '_WIN32' macro In this stage we focus on replacing usage of the WIN macro Change-Id: Ie8a4a63198a6de96bd158ecd707dadafb9c8ea84 Reviewed-on: https://gerrit.libreoffice.org/22393 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
2015-11-16use initialiser list for Sequence<OUString>Noel Grandin
Change-Id: Ia5e47261d1fc6fac2d046656c05a1c5eedb07e02 Reviewed-on: https://gerrit.libreoffice.org/19978 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
2015-10-29com::sun::star->css in starmath,stoc,svgio,svlNoel Grandin
Change-Id: If4308b358a55351f6e951ebf055df076ce4ad4ce Reviewed-on: https://gerrit.libreoffice.org/19667 Reviewed-by: Noel Grandin <noelgrandin@gmail.com> Tested-by: Noel Grandin <noelgrandin@gmail.com>
2015-04-17convert SCRIPTTYPE_ constants to scoped enumNoel Grandin
Change-Id: I5be3980ac865162d8d7626556ca47eca4b0ee433 Reviewed-on: https://gerrit.libreoffice.org/15344 Reviewed-by: Noel Grandin <noelgrandin@gmail.com> Tested-by: Noel Grandin <noelgrandin@gmail.com>
2015-03-11utl::ConfigItem::Commit() should call ClearModified()Michael Stahl
Rename the virtual function, and add a new non-virtual Commit() to do that. Change-Id: I09421df781ba965d6ff638b46cd8214fb3a00022
2014-08-16svl: Remove ASCII art and pointless commentsChris Laplante
Change-Id: Idd8ea0cb7e7d58a29dbfcae084558320efe5fe43 Reviewed-on: https://gerrit.libreoffice.org/10945 Reviewed-by: Thomas Arnhold <thomas@arnhold.org> Tested-by: Thomas Arnhold <thomas@arnhold.org>
2014-02-23Remove unneccessary commentsAlexander Wilms
Change-Id: I939160ae72fecbe3d4a60ce755730bd4c38497fb Reviewed-on: https://gerrit.libreoffice.org/8182 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
2014-02-20svl: sal_Bool -> boolStephan Bergmann
Change-Id: Ic31455a1f5ffffa35d4fdde901dd70734207b6f4
2013-09-03was convertIsoStringToLanguage(), use convertToLanguageTypeWithFallback()Eike Rathke
Change-Id: Ib45634b0baad4ef4c6754b13cee6d92c2bc504f8
2013-07-17After some trials, maybe even I can get things rightFridrich Štrba
Change-Id: Ib553ea1ceff1d09dff86c4a36b896dddab854ba0
2013-07-17Brackets are cheap, so use themFridrich Štrba
Change-Id: If5b539025020a2e9a35fa6e7bc70bcc6a9a4f4c6
2013-07-17Fix MINGW64 build in svlFridrich Štrba
Change-Id: I92370c829c192be4ae480e13f290629e7a85be0c
2013-07-17fdo#62475 removed pointless commentsJelle van der Waa
Change-Id: Id9d579960a9b641b7b2cdf05eabea8bfbfc06bd6 Reviewed-on: https://gerrit.libreoffice.org/4901 Reviewed-by: Norbert Thiebaud <nthiebaud@gmail.com> Tested-by: Norbert Thiebaud <nthiebaud@gmail.com>
2013-07-13use static LanguageTag::convertTo...() for standalone conversionsEike Rathke
If no LanguageTag instance is at hand use the static methods to convert between BCP 47 string, Locale and MS-LangID instead of creating temporary instances. Change-Id: I9597f768078eb81c840e84a5db5617f26bb7dc09
2013-07-12constify these methodsCaolán McNamara
Change-Id: I72173ef6cbea28afe9f349aa57a94cbfd537a851
2013-07-12Related: fdo#54493 determine if a CJK/CTL keyboard is installedMarc Garcia
Change-Id: If21a34c69f58612f8ec2eba1253f325f352962cd
2013-04-07mass removal of rtl:: prefixes for O(U)String*Luboš Luňák
Modules sal, salhelper, cppu, cppuhelper, codemaker (selectively) and odk have kept them, in order not to break external API (the automatic using declaration is LO-internal). Change-Id: I588fc9e0c45b914f824f91c0376980621d730f09
2013-04-05new module i18nlangtagEike Rathke
Moved portions from module i18npool, all of former i18nisolang1 library that now is i18nlangtag. Included are languagetag, isolang and mslangid. This i18nlangtag code is now even used by module comphelper, so disentangling i18npool and making this an own module was needed to not create circular module dependencies. Change-Id: Ib887c3d6dde667403fd22d382310ba5f1a9b0015