diff options
author | Noel <noel.grandin@collabora.co.uk> | 2021-02-12 12:47:09 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2021-02-12 17:38:19 +0100 |
commit | beeed387732f95501b06b5462d450517422b18ba (patch) | |
tree | 834cf523b8cf8ba927ab72ec75d3747b6ffeb7fe /compilerplugins | |
parent | a39a3f1ad1e5e39b09ce474c0f4c0f9f4e174bbe (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.cxx | 27 | ||||
-rw-r--r-- | compilerplugins/clang/test/refcounting.cxx | 6 |
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: */ |