summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorNoel <noel.grandin@collabora.co.uk>2021-02-12 12:47:09 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2021-02-12 17:38:19 +0100
commitbeeed387732f95501b06b5462d450517422b18ba (patch)
tree834cf523b8cf8ba927ab72ec75d3747b6ffeb7fe /compilerplugins
parenta39a3f1ad1e5e39b09ce474c0f4c0f9f4e174bbe (diff)
loplugin:refcounting check for calling delete
Change-Id: I5b723d4d2376a28777e3ee7e9706e5f54fcb55e3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110809 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/refcounting.cxx27
-rw-r--r--compilerplugins/clang/test/refcounting.cxx6
2 files changed, 33 insertions, 0 deletions
diff --git a/compilerplugins/clang/refcounting.cxx b/compilerplugins/clang/refcounting.cxx
index df5805542fce..fa026877680b 100644
--- a/compilerplugins/clang/refcounting.cxx
+++ b/compilerplugins/clang/refcounting.cxx
@@ -56,6 +56,7 @@ public:
bool VisitVarDecl(const VarDecl *);
bool VisitFunctionDecl(const FunctionDecl *);
bool VisitTypeLoc(clang::TypeLoc typeLoc);
+ bool VisitCXXDeleteExpr(const CXXDeleteExpr *);
// Creation of temporaries with one argument are represented by
// CXXFunctionalCastExpr, while any other number of arguments are
@@ -489,6 +490,32 @@ bool RefCounting::VisitTypeLoc(clang::TypeLoc typeLoc)
return true;
}
+bool RefCounting::VisitCXXDeleteExpr(const CXXDeleteExpr * cxxDeleteExpr)
+{
+ if (ignoreLocation(cxxDeleteExpr))
+ return true;
+ StringRef aFileName = getFilenameOfLocation(
+ compiler.getSourceManager().getSpellingLoc(compat::getBeginLoc(cxxDeleteExpr)));
+ if (loplugin::isSamePathname(aFileName, SRCDIR "/cppuhelper/source/weak.cxx"))
+ return true;
+
+ if (!cxxDeleteExpr->getArgument())
+ return true;
+ auto argType = cxxDeleteExpr->getArgument()->getType();
+ if (argType.isNull() || !argType->isPointerType())
+ return true;
+ auto pointeeType = argType->getPointeeType();
+ if (containsOWeakObjectSubclass(pointeeType))
+ {
+ report(
+ DiagnosticsEngine::Warning,
+ "cppu::OWeakObject subclass %0 being deleted via delete, should be managed via rtl::Reference",
+ compat::getBeginLoc(cxxDeleteExpr))
+ << pointeeType
+ << cxxDeleteExpr->getSourceRange();
+ }
+ return true;
+}
bool RefCounting::VisitFieldDecl(const FieldDecl * fieldDecl) {
if (ignoreLocation(fieldDecl)) {
return true;
diff --git a/compilerplugins/clang/test/refcounting.cxx b/compilerplugins/clang/test/refcounting.cxx
index 7e42094407fb..69825e6fc47b 100644
--- a/compilerplugins/clang/test/refcounting.cxx
+++ b/compilerplugins/clang/test/refcounting.cxx
@@ -51,4 +51,10 @@ rtl::Reference<UnoObject> foo2(); // no warning expected
// expected-error@+1 {{cppu::OWeakObject subclass 'UnoObject' being managed via smart pointer, should be managed via rtl::Reference [loplugin:refcounting]}}
void foo3(std::unique_ptr<UnoObject> p);
+void test2(UnoObject* pUnoObject)
+{
+ // expected-error@+1 {{cppu::OWeakObject subclass 'UnoObject' being deleted via delete, should be managed via rtl::Reference [loplugin:refcounting]}}
+ delete pUnoObject;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */