compilerplugins/clang/check.cxx | 36 +++++++++++++++++++++ compilerplugins/clang/check.hxx | 8 ++++ compilerplugins/clang/commaoperator.cxx | 17 +++++++++ compilerplugins/clang/fpcomparison.cxx | 5 ++ compilerplugins/clang/plugin.cxx | 15 +++++++- compilerplugins/clang/pluginhandler.cxx | 5 ++ compilerplugins/clang/redundantcast.cxx | 53 +++++++++++++++++-------------- compilerplugins/clang/stringconcat.cxx | 25 ++++++++++++-- compilerplugins/clang/stringconstant.cxx | 43 +++++++++++++++---------- compilerplugins/clang/vclwidgets.cxx | 14 ++++++-- 10 files changed, 172 insertions(+), 49 deletions(-)
New commits: commit 54aab71ff7c51677176331347074a765f22fd80d Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 14:20:19 2016 +0100 On Windows, #include <process.h> for getpid Change-Id: Ibfb52800cdde99298431dab9da1cb8109658c425 diff --git a/compilerplugins/clang/pluginhandler.cxx b/compilerplugins/clang/pluginhandler.cxx index 89ba8f4..b46079bb1 100644 --- a/compilerplugins/clang/pluginhandler.cxx +++ b/compilerplugins/clang/pluginhandler.cxx @@ -16,8 +16,13 @@ #include <clang/Frontend/FrontendPluginRegistry.h> #include <clang/Lex/PPCallbacks.h> #include <stdio.h> + +#if defined _WIN32 +#include <process.h> +#else #include <sys/stat.h> #include <unistd.h> +#endif /* This source file manages all plugin actions. It is not necessary to modify this commit 35196c32751570d0c4b79f550d6c8723d2936f1c Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 14:16:34 2016 +0100 loplugin:vclwidgets: Adapt check for 'assert' for MSVCRT Change-Id: I12a77b5b53e3a674c1ff1554b560a71605e141a6 diff --git a/compilerplugins/clang/vclwidgets.cxx b/compilerplugins/clang/vclwidgets.cxx index 8a5ac72..3929cdf 100644 --- a/compilerplugins/clang/vclwidgets.cxx +++ b/compilerplugins/clang/vclwidgets.cxx @@ -216,9 +216,17 @@ bool VCLWidgets::VisitCXXDestructorDecl(const CXXDestructorDecl* pCXXDestructorD } } } - // checking for ParenExpr is a hacky way to ignore assert statements in older versions of clang (i.e. <= 3.2) - if (!pCallExpr && !dyn_cast<ParenExpr>(*i)) - nNumExtraStatements++; + if (!pCallExpr) { + auto loc = (*i)->getLocStart(); + if (!compiler.getSourceManager().isMacroBodyExpansion(loc) + || (Lexer::getImmediateMacroName( + loc, compiler.getSourceManager(), + compiler.getLangOpts()) + != "assert")) + { + nNumExtraStatements++; + } + } } bOk = bFoundDisposeOnce && nNumExtraStatements == 0; } commit 83ff2a4f3824cbca7bc61a954aed840a21be4364 Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 14:13:18 2016 +0100 loplugin:stringconstant: Adapt to definition of OSL_THIS_FUNC on Windows Change-Id: I93a23799ad9a76ed9f4f86d69adb610d0962da20 diff --git a/compilerplugins/clang/stringconstant.cxx b/compilerplugins/clang/stringconstant.cxx index 354f235..2afd923 100644 --- a/compilerplugins/clang/stringconstant.cxx +++ b/compilerplugins/clang/stringconstant.cxx @@ -687,6 +687,17 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { { return true; } + // OSL_THIS_FUNC may be defined as "" or as something other + // than a string literal in include/osl/diagnose.h: + auto loc = arg->getLocStart(); + if (compiler.getSourceManager().isMacroBodyExpansion(loc) + && (Lexer::getImmediateMacroName( + loc, compiler.getSourceManager(), + compiler.getLangOpts()) + == "OSL_THIS_FUNC")) + { + return true; + } if (non) { report( DiagnosticsEngine::Warning, commit 9ed9ca611a6abfe3096379ba52a56fd53f07d5a1 Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 14:11:58 2016 +0100 loplugin:stringconcat: Adapt to definition of OSL_THIS_FUNC on Windows Change-Id: I9a2be8c4265095ff2ac5e2216cb08c35c9049bf8 diff --git a/compilerplugins/clang/stringconcat.cxx b/compilerplugins/clang/stringconcat.cxx index fe842f6..a944f4f 100644 --- a/compilerplugins/clang/stringconcat.cxx +++ b/compilerplugins/clang/stringconcat.cxx @@ -36,10 +36,6 @@ Expr const * stripCtor(Expr const * expr) { return e3->getArg(0)->IgnoreParenImpCasts(); } -bool isStringLiteral(Expr const * expr) { - return isa<clang::StringLiteral>(stripCtor(expr)); -} - class StringConcat: public RecursiveASTVisitor<StringConcat>, public loplugin::Plugin { @@ -50,6 +46,9 @@ public: { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } bool VisitCallExpr(CallExpr const * expr); + +private: + bool isStringLiteral(Expr const * expr); }; bool StringConcat::VisitCallExpr(CallExpr const * expr) { @@ -109,6 +108,24 @@ bool StringConcat::VisitCallExpr(CallExpr const * expr) { return true; } +bool StringConcat::isStringLiteral(Expr const * expr) { + expr = stripCtor(expr); + if (!isa<clang::StringLiteral>(expr)) { + return false; + } + // OSL_THIS_FUNC may be defined as "" in include/osl/diagnose.h, so don't + // warn about expressions like 'SAL_INFO(..., OSL_THIS_FUNC << ":")' or + // 'OUString(OSL_THIS_FUNC) + ":"': + auto loc = expr->getLocStart(); + while (compiler.getSourceManager().isMacroArgExpansion(loc)) { + loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc); + } + return !compiler.getSourceManager().isMacroBodyExpansion(loc) + || (Lexer::getImmediateMacroName( + loc, compiler.getSourceManager(), compiler.getLangOpts()) + != "OSL_THIS_FUNC"); +} + loplugin::Plugin::Registration<StringConcat> X("stringconcat"); } commit dbbd2c48b157214fd3e4b912e25ffd0b02976fa4 Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 14:06:42 2016 +0100 Work around problem with poor gperf-generated code under clang-cl Change-Id: Iba3fae8bbecaf5782228be1fb99f196864d79e6b diff --git a/compilerplugins/clang/plugin.cxx b/compilerplugins/clang/plugin.cxx index 143897b..d5b2401 100644 --- a/compilerplugins/clang/plugin.cxx +++ b/compilerplugins/clang/plugin.cxx @@ -41,8 +41,19 @@ bool Plugin::ignoreLocation( SourceLocation loc ) if( compiler.getSourceManager().isInSystemHeader( expansionLoc )) return true; const char* bufferName = compiler.getSourceManager().getPresumedLoc( expansionLoc ).getFilename(); - if( bufferName == NULL - || strncmp( bufferName, SRCDIR "/external/", strlen( SRCDIR "/external/" )) == 0 ) + if (bufferName == NULL + || strncmp( bufferName, SRCDIR "/external/", strlen( SRCDIR "/external/" )) == 0 + || strcmp( bufferName, SRCDIR "/sdext/source/pdfimport/wrapper/keyword_list" ) == 0 ) + // workdir/CustomTarget/sdext/pdfimport/hash.cxx is generated from + // sdext/source/pdfimport/wrapper/keyword_list by gperf, which + // inserts various #line directives denoting the latter into the + // former, but fails to add a #line directive returning back to + // hash.cxx itself before the gperf generated boilerplate, so + // compilers erroneously consider errors in the boilerplate to come + // from keyword_list instead of hash.cxx (for Clang on Linux/macOS + // this is not an issue due to the '#pragma GCC system_header' + // generated into the start of hash.cxx, #if'ed for __GNUC__, but + // for clang-cl it is an issue) return true; if( strncmp( bufferName, WORKDIR, strlen( WORKDIR )) == 0 ) { commit f2ef97dee758cb7b9360ebef08d59672b5e56b0d Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 14:00:18 2016 +0100 loplugin:fpcomparison: Whitelist some Windows-only functions Change-Id: I94f35696ba358a049ee65764d17c62df7889aec7 diff --git a/compilerplugins/clang/fpcomparison.cxx b/compilerplugins/clang/fpcomparison.cxx index 025d4e0..5bc5d95 100644 --- a/compilerplugins/clang/fpcomparison.cxx +++ b/compilerplugins/clang/fpcomparison.cxx @@ -322,6 +322,11 @@ bool FpComparison::ignore(FunctionDecl* function) || dc.Function("testPlotAreaManualLayoutXLSX").Class("Chart2ExportTest").GlobalNamespace() || dc.Function("testLegendManualLayoutXLSX").Class("Chart2ExportTest").GlobalNamespace() || dc.Function("SetScreenNumber").Class("AquaSalFrame").GlobalNamespace() + || dc.Function("encode_glyph").GlobalNamespace() + || dc.Function("LayoutText").Class("SimpleWinLayout").GlobalNamespace() + || dc.Function("DisableFontScaling").Class("WinLayout").GlobalNamespace() + || dc.Function("LayoutText").Class("UniscribeLayout").GlobalNamespace() + || dc.Function("GetTextLayout").Class("WinSalGraphics").GlobalNamespace() || (vclFloatDevicePixel && (dc.Function("Justify").Class("GenericSalLayout").GlobalNamespace() || dc.Function("AdjustLayout").Class("MultiSalLayout").GlobalNamespace()))) commit 09f5ffafc2dcc999acfe5939ce341d27122a4446 Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 13:57:15 2016 +0100 loplugin:commaoperator: Ignore occurrence in FD_SET expansion on Windows Change-Id: I66974c273918d6d887364e7d552e3caf63e16343 diff --git a/compilerplugins/clang/commaoperator.cxx b/compilerplugins/clang/commaoperator.cxx index 21c2b43..c4a61e7 100644 --- a/compilerplugins/clang/commaoperator.cxx +++ b/compilerplugins/clang/commaoperator.cxx @@ -39,6 +39,21 @@ bool CommaOperator::VisitBinaryOperator(const BinaryOperator* binaryOp) if (ignoreLocation(binaryOp)) { return true; } + // Ignore FD_SET expanding to "...} while(0, 0)" in some Microsoft + // winsock2.h (TODO: improve heuristic of determining that the whole + // binaryOp is part of a single macro body expansion): + if (compiler.getSourceManager().isMacroBodyExpansion( + binaryOp->getLocStart()) + && compiler.getSourceManager().isMacroBodyExpansion( + binaryOp->getOperatorLoc()) + && compiler.getSourceManager().isMacroBodyExpansion( + binaryOp->getLocEnd()) + && ignoreLocation( + compiler.getSourceManager().getSpellingLoc( + binaryOp->getOperatorLoc()))) + { + return true; + } if (binaryOp->getOpcode() != BO_Comma) { return true; } commit c052ec5add428b9e22494ada72758bc93de902f6 Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 13:55:52 2016 +0100 Chose better diagnostic location Change-Id: I502da4b93905e64ca5506f24dc1f6bf2bf990dc2 diff --git a/compilerplugins/clang/commaoperator.cxx b/compilerplugins/clang/commaoperator.cxx index 39a2b9c..21c2b43 100644 --- a/compilerplugins/clang/commaoperator.cxx +++ b/compilerplugins/clang/commaoperator.cxx @@ -63,7 +63,7 @@ bool CommaOperator::VisitBinaryOperator(const BinaryOperator* binaryOp) // parent->dump(); report( DiagnosticsEngine::Warning, "comma operator hides code", - binaryOp->getSourceRange().getBegin()) + binaryOp->getOperatorLoc()) << binaryOp->getSourceRange(); return true; } commit 0f22790e6bc936b6de588c30816d6fa59f4a14dc Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 13:52:04 2016 +0100 Generalize typedef-to-void* check in loplugin:redundantcast ...to also cover cases like conversion betwen LPVOID and HANDLE in Windows-only code Change-Id: I934fe89372ee7a12462e7ad4284b9ea2cc73ce5a diff --git a/compilerplugins/clang/check.cxx b/compilerplugins/clang/check.cxx index 33be502..43a7edf 100644 --- a/compilerplugins/clang/check.cxx +++ b/compilerplugins/clang/check.cxx @@ -14,6 +14,16 @@ namespace loplugin { +TypeCheck TypeCheck::NonConstVolatile() const { + return + (!type_.isNull() && !type_.isConstQualified() + && !type_.isVolatileQualified()) + ? *this : TypeCheck(); + // returning TypeCheck(type_.getUnqualifiedType()) instead of *this + // may look tempting, but could remove sugar we might be interested in + // checking for +} + TypeCheck TypeCheck::Const() const { return (!type_.isNull() && type_.isConstQualified() @@ -24,6 +34,32 @@ TypeCheck TypeCheck::Const() const { // checking for } +TypeCheck TypeCheck::Volatile() const { + return + (!type_.isNull() && !type_.isConstQualified() + && type_.isVolatileQualified()) + ? *this : TypeCheck(); + // returning TypeCheck(type_.getUnqualifiedType()) instead of *this + // may look tempting, but could remove sugar we might be interested in + // checking for +} + +TypeCheck TypeCheck::ConstVolatile() const { + return + (!type_.isNull() && type_.isConstQualified() + && type_.isVolatileQualified()) + ? *this : TypeCheck(); + // returning TypeCheck(type_.getUnqualifiedType()) instead of *this + // may look tempting, but could remove sugar we might be interested in + // checking for +} + +TerminalCheck TypeCheck::Void() const { + return TerminalCheck( + !type_.isNull() + && type_->isSpecificBuiltinType(clang::BuiltinType::Void)); +} + TerminalCheck TypeCheck::Char() const { return TerminalCheck( !type_.isNull() diff --git a/compilerplugins/clang/check.hxx b/compilerplugins/clang/check.hxx index 9bfc458..40f205d 100644 --- a/compilerplugins/clang/check.hxx +++ b/compilerplugins/clang/check.hxx @@ -35,8 +35,16 @@ public: explicit operator bool() const { return !type_.isNull(); } + TypeCheck NonConstVolatile() const; + TypeCheck Const() const; + TypeCheck Volatile() const; + + TypeCheck ConstVolatile() const; + + TerminalCheck Void() const; + TerminalCheck Char() const; TerminalCheck AnyBoolean() const; diff --git a/compilerplugins/clang/redundantcast.cxx b/compilerplugins/clang/redundantcast.cxx index 5215b39..6d18f2a 100644 --- a/compilerplugins/clang/redundantcast.cxx +++ b/compilerplugins/clang/redundantcast.cxx @@ -291,29 +291,36 @@ bool RedundantCast::VisitCXXStaticCastExpr(CXXStaticCastExpr const * expr) { { return true; } - // Don't warn about - // - // *pResult = static_cast<oslModule>(RTLD_DEFAULT); - // - // in osl_getModuleHandle (sal/osl/unx/module.cxx) (where oslModule is a - // typedef to void *): - if (loplugin::TypeCheck(t2).Typedef("oslModule").GlobalNamespace() - && !loplugin::TypeCheck(t1).Typedef()) - { - return true; - } - // Dont't warn about - // - // curl_easy_setopt(static_cast<CURL*>(pData), - // CURLOPT_HEADERFUNCTION, - // memory_write_dummy); - // - // in delete_CURL (ucb/source/ucp/ftp/ftploaderthread.cxx) (where CURL is a - // typedef to void): - if (loplugin::TypeCheck(t2).Pointer().Typedef("CURL").GlobalNamespace() - && !loplugin::TypeCheck(t1).Pointer().Typedef()) - { - return true; + // Don't warn if the types are 'void *' and at least one involves a typedef + // (and if both involve typedefs, they're different) (this covers cases like + // 'oslModule', or 'CURL *', or casts between 'LPVOID' and 'HANDLE' in + // Windows-only code): + if (loplugin::TypeCheck(t1).Pointer().NonConstVolatile().Void()) { + if (auto const td1 = t1->getAs<TypedefType>()) { + auto const td2 = t2->getAs<TypedefType>(); + if (td2 == nullptr || td2 != td1) { + return true; + } + } else if (auto const td2 = t2->getAs<TypedefType>()) { + auto const td1 = t1->getAs<TypedefType>(); + if (td1 == nullptr || td1 != td2) { + return true; + } + } else { + auto const pt1 = t1->getAs<clang::PointerType>()->getPointeeType(); + auto const pt2 = t2->getAs<clang::PointerType>()->getPointeeType(); + if (auto const ptd1 = pt1->getAs<TypedefType>()) { + auto const ptd2 = pt2->getAs<TypedefType>(); + if (ptd2 == nullptr || ptd2 != ptd1) { + return true; + } + } else if (auto const ptd2 = pt2->getAs<TypedefType>()) { + auto const ptd1 = pt1->getAs<TypedefType>(); + if (ptd1 == nullptr || ptd1 != ptd2) { + return true; + } + } + } } report( DiagnosticsEngine::Warning, commit ec0665ac8b427b16f1ebc118496d7d2b1831f3fd Author: Stephan Bergmann <[email protected]> Date: Sun Dec 18 13:44:43 2016 +0100 Rename cdecl -> classdecl (MSVC treats the former like a keyword) Change-Id: I1859a92c996b907b8d511cddba25c00c9a52f398 diff --git a/compilerplugins/clang/stringconstant.cxx b/compilerplugins/clang/stringconstant.cxx index d67d41c..354f235 100644 --- a/compilerplugins/clang/stringconstant.cxx +++ b/compilerplugins/clang/stringconstant.cxx @@ -651,8 +651,8 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { if (ignoreLocation(expr)) { return true; } - auto cdecl = expr->getConstructor()->getParent(); - if (loplugin::DeclCheck(cdecl) + auto classdecl = expr->getConstructor()->getParent(); + if (loplugin::DeclCheck(classdecl) .Class("OUString").Namespace("rtl").GlobalNamespace()) { ChangeKind kind; @@ -693,7 +693,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { ("construction of %0 with string constant argument" " containging non-ASCII characters"), expr->getExprLoc()) - << cdecl << expr->getSourceRange(); + << classdecl << expr->getSourceRange(); } if (emb) { report( @@ -701,7 +701,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { ("construction of %0 with string constant argument" " containging embedded NULs"), expr->getExprLoc()) - << cdecl << expr->getSourceRange(); + << classdecl << expr->getSourceRange(); } kind = ChangeKind::Char; pass = n == 0 @@ -761,7 +761,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { " as call of rtl::OUString::isEmpty"), getMemberLocation(call)) << fdecl->getQualifiedNameAsString() - << cdecl << call->getSourceRange(); + << classdecl << call->getSourceRange(); return true; } if (dc.Operator(OO_ExclaimEqual).Namespace("rtl") @@ -774,7 +774,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { " as call of !rtl::OUString::isEmpty"), getMemberLocation(call)) << fdecl->getQualifiedNameAsString() - << cdecl << call->getSourceRange(); + << classdecl << call->getSourceRange(); return true; } if ((dc.Operator(OO_Plus).Namespace("rtl") @@ -788,7 +788,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { " %1 with empty string constant argument"), getMemberLocation(call)) << fdecl->getQualifiedNameAsString() - << cdecl << call->getSourceRange(); + << classdecl << call->getSourceRange(); return true; } if (dc.Operator(OO_Equal).Class("OUString") @@ -801,7 +801,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { " as call of rtl::OUString::clear"), getMemberLocation(call)) << fdecl->getQualifiedNameAsString() - << cdecl << call->getSourceRange(); + << classdecl << call->getSourceRange(); return true; } } else { @@ -817,7 +817,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { + " as operator =="), getMemberLocation(call)) << fdecl->getQualifiedNameAsString() - << cdecl << call->getSourceRange(); + << classdecl << call->getSourceRange(); return true; } if ((dc.Operator(OO_Plus).Namespace("rtl") @@ -871,7 +871,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { + (" in call of %1 as construction of" " OUStringLiteral1")), getMemberLocation(expr)) - << cdecl + << classdecl << fdecl->getQualifiedNameAsString() << expr->getSourceRange(); } else { @@ -881,7 +881,7 @@ bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { + describeChangeKind(kind) + " in call of %1"), getMemberLocation(expr)) - << cdecl + << classdecl << fdecl->getQualifiedNameAsString() << expr->getSourceRange(); } @@ -1184,9 +1184,9 @@ void StringConstant::reportChange( return; } } else if (isa<CXXConstructExpr>(call)) { - auto cdecl = cast<CXXConstructExpr>(call)->getConstructor() - ->getParent(); - loplugin::DeclCheck dc(cdecl); + auto classdecl = cast<CXXConstructExpr>(call) + ->getConstructor()->getParent(); + loplugin::DeclCheck dc(classdecl); if (dc.Class("OUString").Namespace("rtl").GlobalNamespace() || (dc.Class("OUStringBuffer").Namespace("rtl") .GlobalNamespace())) @@ -1200,7 +1200,7 @@ void StringConstant::reportChange( + (" with empty string constant argument as" " default construction of %0")), getMemberLocation(call)) - << cdecl->getQualifiedNameAsString() + << classdecl->getQualifiedNameAsString() << call->getSourceRange(); } else { assert(pass == PassThrough::NonEmptyConstantString); @@ -1210,7 +1210,7 @@ void StringConstant::reportChange( + describeChangeKind(kind) + " in construction of %0"), getMemberLocation(expr)) - << cdecl->getQualifiedNameAsString() + << classdecl->getQualifiedNameAsString() << expr->getSourceRange(); } return; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
