summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2017-08-17 11:35:37 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2017-08-17 13:18:34 +0200
commitb0d7b8fa63109117ec19864ddd2462683088d1e3 (patch)
tree48ef8f5c1809be477575562a5d02c84e3b0c7618 /compilerplugins
parentd64a7f4ba80fa2a0a0ad2bddc6906ab6b78a23c8 (diff)
new loplugin convertuintptr
an experiment to see if I can make the process of eliminating sal_uIntPtr a little easier Change-Id: I808185fbf18826cb9ab5612a7be4148d52045957
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/convertuintptr.cxx105
-rw-r--r--compilerplugins/clang/droplong.cxx2
-rw-r--r--compilerplugins/clang/test/convertuintptr.cxx20
3 files changed, 125 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: */