diff options
-rw-r--r-- | compilerplugins/clang/convertuintptr.cxx | 105 | ||||
-rw-r--r-- | compilerplugins/clang/droplong.cxx | 2 | ||||
-rw-r--r-- | compilerplugins/clang/test/convertuintptr.cxx | 20 | ||||
-rw-r--r-- | solenv/CompilerTest_compilerplugins_clang.mk | 1 |
4 files changed, 126 insertions, 2 deletions
diff --git a/compilerplugins/clang/convertuintptr.cxx b/compilerplugins/clang/convertuintptr.cxx new file mode 100644 index 000000000000..77eb1b4f8616 --- /dev/null +++ b/compilerplugins/clang/convertuintptr.cxx @@ -0,0 +1,105 @@ +/* -*- 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/. + */ + +#include <memory> +#include <cassert> +#include <string> +#include <iostream> +#include <fstream> +#include <set> +#include "plugin.hxx" +#include "check.hxx" + +/** + plugin to help to when converting code from sal_uIntPtr to something more precise. + */ +namespace { + +class ConvertUIntPtr: + public RecursiveASTVisitor<ConvertUIntPtr>, public loplugin::Plugin +{ +public: + explicit ConvertUIntPtr(InstantiationData const & data): Plugin(data) {} + + virtual void run() override + { + std::string fn( compiler.getSourceManager().getFileEntryForID( + compiler.getSourceManager().getMainFileID())->getName() ); + normalizeDotDotInFilePath(fn); + // using sal_uIntPtr as in-between type when converting void* to rtl_TextEncoding + if (fn == SRCDIR "/sal/osl/unx/thread.cxx") + return; + // too much magic + if (fn == SRCDIR "/sal/rtl/alloc_arena.cxx") + return; + if (fn == SRCDIR "/sal/rtl/alloc_cache.cxx") + return; + // TODO not sure what is going on here + if (fn == SRCDIR "/tools/source/generic/bigint.cxx") + return; + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); + } + + bool VisitImplicitCastExpr(ImplicitCastExpr const *); +private: + bool isIntPtr(QualType qt); +}; + +bool ConvertUIntPtr::VisitImplicitCastExpr(ImplicitCastExpr const * castExpr) +{ + if (ignoreLocation(castExpr)) + return true; + + if (castExpr->getCastKind() == CK_LValueToRValue) + return true; + if (isa<IntegerLiteral>(castExpr->IgnoreCasts())) + return true; + // ignore literals like "-123" + if (isa<UnaryOperator>(castExpr->IgnoreCasts())) + return true; + + bool isSrcIntPtr = isIntPtr(castExpr->getSubExpr()->getType()); + bool isDestIntPtr = isIntPtr(castExpr->getType()); + + if (!isSrcIntPtr && !isDestIntPtr) + return true; + + // exclude casting between sal_uIntPtr <-> sal_IntPtr + if (isSrcIntPtr && isDestIntPtr) + return true; + + if (isSrcIntPtr && loplugin::TypeCheck(castExpr->getType()).AnyBoolean()) + return true; + + report( + DiagnosticsEngine::Warning, + "cast from %0 to %1", + castExpr->getExprLoc()) + << castExpr->getSubExpr()->getType() + << castExpr->getType() + << castExpr->getSourceRange(); + + return true; +} + +bool ConvertUIntPtr::isIntPtr(QualType qt) +{ + auto tc = loplugin::TypeCheck(qt); + if (!tc.Typedef()) + return false; + TypedefType const * typedefType = qt->getAs<TypedefType>(); + auto name = typedefType->getDecl()->getName(); + return name == "sal_uIntPtr" || name == "sal_IntPtr"; +} + +loplugin::Plugin::Registration< ConvertUIntPtr > X("convertuintptr", false); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/compilerplugins/clang/droplong.cxx b/compilerplugins/clang/droplong.cxx index a6ef33006d9d..fe5675b36d2f 100644 --- a/compilerplugins/clang/droplong.cxx +++ b/compilerplugins/clang/droplong.cxx @@ -57,8 +57,6 @@ public: TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } - bool shouldVisitTemplateInstantiations () const { return true; } - bool VisitBinAssign(BinaryOperator const *); bool VisitVarDecl(VarDecl const *); bool VisitCastExpr(CastExpr const *); diff --git a/compilerplugins/clang/test/convertuintptr.cxx b/compilerplugins/clang/test/convertuintptr.cxx new file mode 100644 index 000000000000..8789394c541f --- /dev/null +++ b/compilerplugins/clang/test/convertuintptr.cxx @@ -0,0 +1,20 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include <tools/solar.h> + +int main() +{ + sal_uIntPtr x = 1; + sal_uInt32 y = x; // expected-error {{cast from 'sal_uIntPtr' (aka 'unsigned long') to 'sal_uInt32' (aka 'unsigned int') [loplugin:convertuintptr]}} + y = x; // expected-error {{cast from 'sal_uIntPtr' (aka 'unsigned long') to 'sal_uInt32' (aka 'unsigned int') [loplugin:convertuintptr]}} + (void)y; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/solenv/CompilerTest_compilerplugins_clang.mk b/solenv/CompilerTest_compilerplugins_clang.mk index 4f1b41149536..59f572ce1374 100644 --- a/solenv/CompilerTest_compilerplugins_clang.mk +++ b/solenv/CompilerTest_compilerplugins_clang.mk @@ -12,6 +12,7 @@ $(eval $(call gb_CompilerTest_CompilerTest,compilerplugins_clang)) $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \ compilerplugins/clang/test/casttovoid \ compilerplugins/clang/test/constparams \ + compilerplugins/clang/test/convertuintptr \ compilerplugins/clang/test/cppunitassertequals \ compilerplugins/clang/test/datamembershadow \ compilerplugins/clang/test/droplong \ |