chart2/source/controller/dialogs/dlg_Theme.cxx            |    1 
 chart2/source/controller/sidebar/ChartThemeControl.cxx    |    1 
 chart2/source/controller/sidebar/ChartThemePanel.cxx      |    1 
 compilerplugins/clang/scopedvclptr.cxx                    |  282 ++++++++++++++
 compilerplugins/clang/test/scopedvclptr.cxx               |   92 ++++
 drawinglayer/source/processor2d/vclhelperbufferdevice.cxx |    1 
 sc/source/ui/inc/checklistmenu.hxx                        |    1 
 solenv/CompilerTest_compilerplugins_clang.mk              |    1 
 svx/source/tbxctrls/StylesPreviewWindow.cxx               |    2 
 svx/source/tbxctrls/SvxColorIconView.cxx                  |    1 
 svx/source/tbxctrls/fontworkgallery.cxx                   |    1 
 svx/source/tbxctrls/tbxcolorupdate.cxx                    |    2 
 svx/source/unodraw/UnoGraphicExporter.cxx                 |    1 
 sw/source/core/doc/DocumentDeviceManager.cxx              |    2 
 vcl/inc/salvtables.hxx                                    |    1 
 vcl/source/app/salvtables.cxx                             |    3 
 vcl/source/window/syswin.cxx                              |    1 
 vcl/unx/generic/gdi/cairo_xlib_cairo.cxx                  |    1 
 vcl/unx/gtk3/gtkcairo.cxx                                 |    1 
 vcl/unx/gtk3/gtkinst.cxx                                  |    5 
 20 files changed, 400 insertions(+), 1 deletion(-)

New commits:
commit 3a3251eee5afcef78f1851d069d8e5824782fb12
Author:     Andras Timar <[email protected]>
AuthorDate: Sat Feb 21 16:17:57 2026 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Tue Feb 24 11:47:55 2026 +0100

    new loplugin:scopedvclptr to detect VclPtr<VirtualDevice> leaks
    
    Two checks to prevent GDI handle leaks on Windows:
    
    1. Local VclPtr<VirtualDevice> created via VclPtr::Create() but never
       disposed - should use ScopedVclPtr<VirtualDevice> instead.
       Suppressed when the variable is returned (factory), explicitly
       disposeAndClear()'d, or not initialized via VclPtr::Create().
    
    2. Functions returning VclPtr<VirtualDevice> - should return
       ScopedVclPtr<VirtualDevice> so callers get automatic cleanup.
    
    Both checks support // [-loplugin:scopedvclptr] suppression comments
    for cases where the code is correct but the plugin cannot prove it
    (e.g. ownership transfer to a container/member, virtual overrides
    whose base class dictates the return type).
    
    17 existing false-positive sites suppressed across vcl, svx, sw,
    chart2, sc, drawinglayer, and editeng.
    Added additional 7 suppression comments to GTK-only code that
    doesn't affect Windows.
    
    Change-Id: I6556f2d4e27ab34d135c3fbc5a6c18e04a3e3e0e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/199957
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/chart2/source/controller/dialogs/dlg_Theme.cxx 
b/chart2/source/controller/dialogs/dlg_Theme.cxx
index a60b6e96a2a9..f75b2d977f68 100644
--- a/chart2/source/controller/dialogs/dlg_Theme.cxx
+++ b/chart2/source/controller/dialogs/dlg_Theme.cxx
@@ -77,6 +77,7 @@ SchThemeDlg::SchThemeDlg(weld::Window* pWindow, 
ChartController* pController, bo
     mxThemeIconView->select(0);
 }
 
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> SchThemeDlg::makeImage(int nIndex)
 {
     // clone the chart
diff --git a/chart2/source/controller/sidebar/ChartThemeControl.cxx 
b/chart2/source/controller/sidebar/ChartThemeControl.cxx
index 531fe569f631..de356c1ea24d 100644
--- a/chart2/source/controller/sidebar/ChartThemeControl.cxx
+++ b/chart2/source/controller/sidebar/ChartThemeControl.cxx
@@ -194,6 +194,7 @@ ChartThemePopup::~ChartThemePopup()
     mxManageChartStylesButton.reset();
 }
 
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> ChartThemePopup::makeImage(int nIndex)
 {
     VclPtr<VirtualDevice> device1 = 
VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA);
diff --git a/chart2/source/controller/sidebar/ChartThemePanel.cxx 
b/chart2/source/controller/sidebar/ChartThemePanel.cxx
index 9e9038d625f0..c9c11b0bee92 100644
--- a/chart2/source/controller/sidebar/ChartThemePanel.cxx
+++ b/chart2/source/controller/sidebar/ChartThemePanel.cxx
@@ -96,6 +96,7 @@ void ThemeWrapper::updateData() const
 
 void ThemeWrapper::select(const sal_uInt32 nIndex) { 
mpController->setTheme(nIndex); }
 
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> ThemeWrapper::makePictureFromThemedChart(sal_uInt32 
nIndex)
 {
     if (mpController)
diff --git a/compilerplugins/clang/scopedvclptr.cxx 
b/compilerplugins/clang/scopedvclptr.cxx
new file mode 100644
index 000000000000..9689a8cfec14
--- /dev/null
+++ b/compilerplugins/clang/scopedvclptr.cxx
@@ -0,0 +1,282 @@
+/* -*- 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 <string>
+
+#include "check.hxx"
+#include "plugin.hxx"
+#include "config_clang.h"
+
+/**
+ * Two checks to prevent GDI handle leaks on Windows:
+ *
+ * 1. Local VclPtr<VirtualDevice> created via VclPtr::Create() but never
+ *    disposed — should use ScopedVclPtr<VirtualDevice> instead.
+ *    Suppressed when the variable is:
+ *      - returned from the function (factory pattern)
+ *      - explicitly disposeAndClear()'d / clear()'d
+ *      - not initialized via VclPtr::Create() (borrowing a shared reference)
+ *
+ * 2. Functions returning VclPtr<VirtualDevice> — should return
+ *    ScopedVclPtr<VirtualDevice> so callers get automatic cleanup.
+ *
+ * VclPtr does NOT call dispose() in its destructor.  ScopedVclPtr does.
+ */
+
+namespace
+{
+// ---------------------------------------------------------------------------
+// helpers
+// ---------------------------------------------------------------------------
+
+/// Strip implicit conversions, copy/move constructors, and temporary
+/// materializations to find the underlying DeclRefExpr (if any).
+static const DeclRefExpr* getUnderlyingDeclRef(const Expr* pExpr)
+{
+    if (!pExpr)
+        return nullptr;
+    pExpr = pExpr->IgnoreImplicit();
+    if (auto* pDeclRef = dyn_cast<DeclRefExpr>(pExpr))
+        return pDeclRef;
+    if (auto* pConstruct = dyn_cast<CXXConstructExpr>(pExpr))
+    {
+        if (pConstruct->getNumArgs() == 1)
+            return getUnderlyingDeclRef(pConstruct->getArg(0));
+    }
+    if (auto* pMaterialize = dyn_cast<MaterializeTemporaryExpr>(pExpr))
+        return getUnderlyingDeclRef(pMaterialize->getSubExpr());
+    if (auto* pBind = dyn_cast<CXXBindTemporaryExpr>(pExpr))
+        return getUnderlyingDeclRef(pBind->getSubExpr());
+    return nullptr;
+}
+
+/// Is the VarDecl directly returned from any ReturnStmt in the function body?
+/// Only matches when the variable itself is the return value (possibly through
+/// implicit conversions), NOT when it is merely referenced inside the return
+/// expression (e.g. pVar->GetSomething()).
+static bool isReturnedFromStmt(const Stmt* pStmt, const VarDecl* pVarDecl)
+{
+    if (!pStmt)
+        return false;
+    if (auto* pReturn = dyn_cast<ReturnStmt>(pStmt))
+    {
+        auto* pDeclRef = getUnderlyingDeclRef(pReturn->getRetValue());
+        if (pDeclRef && pDeclRef->getDecl() == pVarDecl)
+            return true;
+    }
+    for (auto* child : pStmt->children())
+    {
+        if (isReturnedFromStmt(child, pVarDecl))
+            return true;
+    }
+    return false;
+}
+
+/// Is disposeAndClear() or clear() called on the VarDecl somewhere in the 
body?
+static bool isDisposedInStmt(const Stmt* pStmt, const VarDecl* pVarDecl)
+{
+    if (!pStmt)
+        return false;
+    if (auto* pCallExpr = dyn_cast<CXXMemberCallExpr>(pStmt))
+    {
+        if (auto* pCallee = pCallExpr->getDirectCallee())
+        {
+            auto check = loplugin::DeclCheck(pCallee);
+            if (check.Function("disposeAndClear") || check.Function("clear"))
+            {
+                // Check that the object being called is our VarDecl
+                if (auto* pMemberExpr = 
dyn_cast<MemberExpr>(pCallExpr->getCallee()))
+                {
+                    auto* pBase = pMemberExpr->getBase()->IgnoreImplicit();
+                    if (auto* pDeclRef = dyn_cast<DeclRefExpr>(pBase))
+                    {
+                        if (pDeclRef->getDecl() == pVarDecl)
+                            return true;
+                    }
+                }
+            }
+        }
+    }
+    for (auto* child : pStmt->children())
+    {
+        if (isDisposedInStmt(child, pVarDecl))
+            return true;
+    }
+    return false;
+}
+
+/// Does the expression tree contain a call to VclPtr<...>::Create()?
+static bool containsVclPtrCreate(const Stmt* pStmt)
+{
+    if (!pStmt)
+        return false;
+    if (auto* pCallExpr = dyn_cast<CallExpr>(pStmt))
+    {
+        if (auto* pCallee = pCallExpr->getDirectCallee())
+        {
+            if (pCallee->getNameAsString() == "Create")
+            {
+                if (auto* pMethodDecl = dyn_cast<CXXMethodDecl>(pCallee))
+                {
+                    if (loplugin::DeclCheck(pMethodDecl)
+                            .MemberFunction()
+                            .Class("VclPtr")
+                            .GlobalNamespace())
+                        return true;
+                }
+            }
+        }
+    }
+    for (auto* child : pStmt->children())
+    {
+        if (containsVclPtrCreate(child))
+            return true;
+    }
+    return false;
+}
+
+// ---------------------------------------------------------------------------
+// plugin
+// ---------------------------------------------------------------------------
+
+class ScopedVclPtrCheck : public loplugin::FilteringPlugin<ScopedVclPtrCheck>
+{
+public:
+    explicit ScopedVclPtrCheck(loplugin::InstantiationData const& data)
+        : FilteringPlugin(data)
+    {
+    }
+
+    virtual bool preRun() override
+    {
+        StringRef fn(handler.getMainFileName());
+        if (loplugin::isSamePathname(fn, SRCDIR "/include/vcl/vclptr.hxx"))
+            return false;
+        return true;
+    }
+
+    virtual void run() override
+    {
+        if (preRun())
+            TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
+    }
+
+    bool VisitVarDecl(const VarDecl*);
+    bool VisitFunctionDecl(const FunctionDecl*);
+
+private:
+    bool isVclPtrToVirtualDevice(QualType qType);
+};
+
+bool ScopedVclPtrCheck::isVclPtrToVirtualDevice(QualType qType)
+{
+    auto check = loplugin::TypeCheck(qType);
+    if (!check.Class("VclPtr").GlobalNamespace())
+        return false;
+
+    const clang::Type* pType = qType.getTypePtr();
+    if (!pType)
+        return false;
+
+    const CXXRecordDecl* pRecordDecl = pType->getAsCXXRecordDecl();
+    if (!pRecordDecl)
+        return false;
+
+    const auto* pTemplate = 
dyn_cast<ClassTemplateSpecializationDecl>(pRecordDecl);
+    if (!pTemplate)
+        return false;
+
+    if (pTemplate->getTemplateArgs().size() < 1)
+        return false;
+
+    const TemplateArgument& rArg = pTemplate->getTemplateArgs()[0];
+    if (rArg.getKind() != TemplateArgument::ArgKind::Type)
+        return false;
+
+    return 
bool(loplugin::TypeCheck(rArg.getAsType()).Class("VirtualDevice").GlobalNamespace());
+}
+
+bool ScopedVclPtrCheck::VisitVarDecl(const VarDecl* pVarDecl)
+{
+    if (ignoreLocation(pVarDecl))
+        return true;
+
+    if (isa<ParmVarDecl>(pVarDecl))
+        return true;
+    if (isa<FieldDecl>(pVarDecl))
+        return true;
+    if (pVarDecl->hasGlobalStorage())
+        return true;
+
+    if (!isVclPtrToVirtualDevice(pVarDecl->getType()))
+        return true;
+
+    // Only warn when the variable is initialized via VclPtr::Create().
+    // Variables initialized from other function calls are typically borrowing
+    // a shared/cached/member-owned device, not creating a new one.
+    auto* pInit = pVarDecl->getInit();
+    if (!pInit || !containsVclPtrCreate(pInit))
+        return true;
+
+    auto* pFuncDecl = dyn_cast<FunctionDecl>(pVarDecl->getDeclContext());
+    if (pFuncDecl && pFuncDecl->hasBody())
+    {
+        const Stmt* pBody = pFuncDecl->getBody();
+
+        // Factory pattern: the local is returned to the caller.
+        if (isReturnedFromStmt(pBody, pVarDecl))
+            return true;
+
+        // Manual lifecycle: disposeAndClear() or clear() is called explicitly.
+        if (isDisposedInStmt(pBody, pVarDecl))
+            return true;
+    }
+
+    if (suppressWarningAt(pVarDecl->getLocation()))
+        return true;
+
+    report(DiagnosticsEngine::Warning,
+           "use ScopedVclPtr<VirtualDevice> instead of VclPtr<VirtualDevice>"
+           " for local variables to prevent GDI handle leaks"
+           " [loplugin:scopedvclptr]",
+           pVarDecl->getLocation())
+        << pVarDecl->getSourceRange();
+
+    return true;
+}
+
+bool ScopedVclPtrCheck::VisitFunctionDecl(const FunctionDecl* pFuncDecl)
+{
+    if (ignoreLocation(pFuncDecl))
+        return true;
+
+    if (!pFuncDecl->isThisDeclarationADefinition())
+        return true;
+
+    if (!isVclPtrToVirtualDevice(pFuncDecl->getReturnType()))
+        return true;
+
+    if (suppressWarningAt(pFuncDecl->getLocation()))
+        return true;
+
+    report(DiagnosticsEngine::Warning,
+           "use ScopedVclPtr<VirtualDevice> as return type instead of"
+           " VclPtr<VirtualDevice> to prevent GDI handle leaks"
+           " [loplugin:scopedvclptr]",
+           pFuncDecl->getLocation())
+        << pFuncDecl->getSourceRange();
+
+    return true;
+}
+
+loplugin::Plugin::Registration<ScopedVclPtrCheck> scopedvclptr("scopedvclptr");
+
+} // namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/compilerplugins/clang/test/scopedvclptr.cxx 
b/compilerplugins/clang/test/scopedvclptr.cxx
new file mode 100644
index 000000000000..1f5a02432110
--- /dev/null
+++ b/compilerplugins/clang/test/scopedvclptr.cxx
@@ -0,0 +1,92 @@
+/* -*- 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 <sal/config.h>
+
+#include <vcl/vclptr.hxx>
+#include <vcl/vclreferencebase.hxx>
+
+// Minimal VirtualDevice stub — the plugin checks for 
Class("VirtualDevice").GlobalNamespace()
+class VirtualDevice : public VclReferenceBase
+{
+public:
+    void dispose() override { VclReferenceBase::dispose(); }
+    ~VirtualDevice() override { disposeOnce(); }
+};
+
+// --- Cases that SHOULD warn (local variable) ---
+
+// Local VclPtr<VirtualDevice> created via ::Create(), not disposed, not 
returned
+void bad_local()
+{
+    VclPtr<VirtualDevice>
+        pVDev // expected-error {{use ScopedVclPtr<VirtualDevice> instead of 
VclPtr<VirtualDevice> for local variables to prevent GDI handle leaks 
[loplugin:scopedvclptr]}}
+        = VclPtr<VirtualDevice>::Create();
+    (void)pVDev;
+}
+
+// --- Cases that SHOULD warn (return type) ---
+
+// Function returning VclPtr<VirtualDevice> should return ScopedVclPtr
+VclPtr<VirtualDevice>
+bad_return_type() // expected-error {{use ScopedVclPtr<VirtualDevice> as 
return type instead of VclPtr<VirtualDevice> to prevent GDI handle leaks 
[loplugin:scopedvclptr]}}
+{
+    VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create();
+    return pVDev;
+}
+
+// --- Cases that should NOT warn ---
+
+// ScopedVclPtr local is fine
+void good_scoped()
+{
+    ScopedVclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create();
+    (void)pVDev;
+}
+
+// Factory returning ScopedVclPtr: no warnings at all
+ScopedVclPtr<VirtualDevice> good_factory_scoped()
+{
+    VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create();
+    return pVDev;
+}
+
+// Using VclPtr in return expression is NOT the same as returning it
+VirtualDevice* bad_use_in_return()
+{
+    VclPtr<VirtualDevice>
+        pVDev // expected-error {{use ScopedVclPtr<VirtualDevice> instead of 
VclPtr<VirtualDevice> for local variables to prevent GDI handle leaks 
[loplugin:scopedvclptr]}}
+        = VclPtr<VirtualDevice>::Create();
+    return pVDev.get();
+}
+
+// Explicit disposeAndClear: developer manages lifecycle manually
+void good_explicit_dispose()
+{
+    VclPtr<VirtualDevice> pVDev = VclPtr<VirtualDevice>::Create();
+    (void)pVDev;
+    pVDev.disposeAndClear();
+}
+
+// Borrowing: initialized from a function call, not VclPtr::Create()
+VclPtr<VirtualDevice> GetSharedDevice();
+void good_borrow()
+{
+    VclPtr<VirtualDevice> pVDev = GetSharedDevice();
+    (void)pVDev;
+}
+
+// No initializer: variable declared but not created via ::Create()
+void good_no_init()
+{
+    VclPtr<VirtualDevice> pVDev;
+    (void)pVDev;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx 
b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index 6b6499a8b539..8362e8387122 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -137,6 +137,7 @@ bool VDevBuffer::isSizeSuitable(const 
VclPtr<VirtualDevice>& device, const Size&
     return false;
 }
 
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> VDevBuffer::alloc(OutputDevice& rOutDev, const Size& 
rSizePixel)
 {
     std::unique_lock aGuard(m_aMutex);
diff --git a/sc/source/ui/inc/checklistmenu.hxx 
b/sc/source/ui/inc/checklistmenu.hxx
index d0d055627668..b6f3384bd76c 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -385,6 +385,7 @@ public:
 
     ScViewData& GetViewData() const { return mrParentControl.GetViewData(); }
     ScCheckListMenuControl::ExtendedData* getExtendedData() { return 
mrParentControl.getExtendedData(); }
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> create_virtual_device() const { return 
mxMenu->create_virtual_device(); }
 
     /**
diff --git a/solenv/CompilerTest_compilerplugins_clang.mk 
b/solenv/CompilerTest_compilerplugins_clang.mk
index eb74020d5ca6..0ca6721f288b 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -77,6 +77,7 @@ $(eval $(call 
gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
     compilerplugins/clang/test/salcall \
     compilerplugins/clang/test/sallogareas \
     compilerplugins/clang/test/salunicodeliteral \
+    compilerplugins/clang/test/scopedvclptr \
     compilerplugins/clang/test/selfinit \
     compilerplugins/clang/test/simplifyconstruct \
     compilerplugins/clang/test/simplifydynamiccast \
diff --git a/svx/source/tbxctrls/StylesPreviewWindow.cxx 
b/svx/source/tbxctrls/StylesPreviewWindow.cxx
index a9a786fe4b65..56324cd9aa7f 100644
--- a/svx/source/tbxctrls/StylesPreviewWindow.cxx
+++ b/svx/source/tbxctrls/StylesPreviewWindow.cxx
@@ -587,7 +587,7 @@ IMPL_LINK(StylesPreviewWindow_Base, GetPreviewImage, const 
weld::encoded_image_q
     return true;
 }
 
-VclPtr<VirtualDevice>
+VclPtr<VirtualDevice> // [-loplugin:scopedvclptr]
 StylesPreviewWindow_Base::GetCachedPreview(const StylePreviewDescriptor& 
rStyle)
 {
     auto aFound = StylePreviewCache::Get().find(rStyle.translatedName);
diff --git a/svx/source/tbxctrls/SvxColorIconView.cxx 
b/svx/source/tbxctrls/SvxColorIconView.cxx
index 43018ff9b084..bde726dd6488 100644
--- a/svx/source/tbxctrls/SvxColorIconView.cxx
+++ b/svx/source/tbxctrls/SvxColorIconView.cxx
@@ -92,6 +92,7 @@ void SvxColorIconView::addEntriesForColorSet(weld::IconView& 
pIconView,
     }
 }
 
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> SvxColorIconView::createColorDevice()
 {
     const sal_uInt32 nEdgeLength = getEntryEdgeLength() - 2;
diff --git a/svx/source/tbxctrls/fontworkgallery.cxx 
b/svx/source/tbxctrls/fontworkgallery.cxx
index 3b8af2b8c65c..975a87add992 100644
--- a/svx/source/tbxctrls/fontworkgallery.cxx
+++ b/svx/source/tbxctrls/fontworkgallery.cxx
@@ -103,6 +103,7 @@ void FontWorkGalleryDialog::initFavorites(sal_uInt16 
nThemeId)
 
         if (GalleryExplorer::GetSdrObj(nThemeId, nModelPos, pModel, &aThumb) 
&& !aThumb.IsEmpty())
         {
+            // [-loplugin:scopedvclptr]
             VclPtr< VirtualDevice > pVDev = VclPtr<VirtualDevice>::Create();
             const Point aNull(0, 0);
 
diff --git a/svx/source/tbxctrls/tbxcolorupdate.cxx 
b/svx/source/tbxctrls/tbxcolorupdate.cxx
index 9c36ee157019..aa5681f4a9d3 100644
--- a/svx/source/tbxctrls/tbxcolorupdate.cxx
+++ b/svx/source/tbxctrls/tbxcolorupdate.cxx
@@ -193,6 +193,7 @@ namespace svx
         mpTbx->SetItemImage(mnBtnId, Image(aGraphic.GetXGraphic()));
     }
 
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> VclToolboxButtonColorUpdater::CreateVirtualDevice() 
const
     {
         return VclPtr<VirtualDevice>::Create(*mpTbx->GetOutDev());
@@ -347,6 +348,7 @@ namespace svx
         mpTbx->set_item_image(msBtnId, pVirDev);
     }
 
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> ToolboxButtonColorUpdater::CreateVirtualDevice() 
const
     {
         return mpTbx->create_virtual_device();
diff --git a/svx/source/unodraw/UnoGraphicExporter.cxx 
b/svx/source/unodraw/UnoGraphicExporter.cxx
index 57c176edec47..90285a974d3d 100644
--- a/svx/source/unodraw/UnoGraphicExporter.cxx
+++ b/svx/source/unodraw/UnoGraphicExporter.cxx
@@ -300,6 +300,7 @@ IMPL_LINK(GraphicExporter, CalcFieldValueHdl, 
EditFieldInfo*, pInfo, void)
 
     @return the returned VirtualDevice is owned by the caller
 */
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> GraphicExporter::CreatePageVDev( SdrPage* pPage, 
tools::Long nWidthPixel, tools::Long nHeightPixel ) const
 {
     VclPtr<VirtualDevice>  pVDev = VclPtr<VirtualDevice>::Create();
diff --git a/sw/source/core/doc/DocumentDeviceManager.cxx 
b/sw/source/core/doc/DocumentDeviceManager.cxx
index 690a183e1fdc..f55d60042c49 100644
--- a/sw/source/core/doc/DocumentDeviceManager.cxx
+++ b/sw/source/core/doc/DocumentDeviceManager.cxx
@@ -259,8 +259,10 @@ DocumentDeviceManager::~DocumentDeviceManager()
 VirtualDevice& DocumentDeviceManager::CreateVirtualDevice_() const
 {
 #ifdef IOS
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> pNewVir = 
VclPtr<VirtualDevice>::Create(DeviceFormat::GRAYSCALE);
 #else
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> pNewVir = 
VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA);
 #endif
 
diff --git a/vcl/inc/salvtables.hxx b/vcl/inc/salvtables.hxx
index 850c3f85fdcb..5e3e02f4dbdc 100644
--- a/vcl/inc/salvtables.hxx
+++ b/vcl/inc/salvtables.hxx
@@ -899,6 +899,7 @@ public:
         }
     }
 
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> create_render_virtual_device() const override
     {
         auto xRet = VclPtr<VirtualDevice>::Create();
diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 78adf725cc76..0b68dfc142b3 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -683,6 +683,7 @@ OUString SalInstanceWidget::escape_ui_str(const OUString& 
rLabel) const
     return rLabel.replaceAll("~", "~~");
 }
 
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> SalInstanceWidget::create_virtual_device() const
 {
     // create with (annoying) separate alpha layer that LibreOffice itself uses
@@ -1703,6 +1704,7 @@ OUString 
SalInstanceWindow::get_window_state(vcl::WindowDataMask nMask) const
 
 SystemEnvData SalInstanceWindow::get_system_data() const { return 
*m_xWindow->GetSystemData(); }
 
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> SalInstanceWindow::screenshot()
 {
     SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get());
@@ -7024,6 +7026,7 @@ public:
         return 0;
     }
 
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> create_render_virtual_device() const override
     {
         return VclPtr<VirtualDevice>::Create();
diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx
index 4414b135f4a2..d022ae41dc3a 100644
--- a/vcl/source/window/syswin.cxx
+++ b/vcl/source/window/syswin.cxx
@@ -1120,6 +1120,7 @@ void SystemWindow::ImplDeferredInit(vcl::Window* 
/*pParent*/, WinBits /*nBits*/)
     SAL_WARN("vcl.layout", "SystemWindow in layout without doDeferredInit 
impl");
 }
 
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> SystemWindow::createScreenshot()
 {
     // same prerequisites as in Execute()
diff --git a/vcl/unx/generic/gdi/cairo_xlib_cairo.cxx 
b/vcl/unx/generic/gdi/cairo_xlib_cairo.cxx
index 87758f24d98e..42530e1c818a 100644
--- a/vcl/unx/generic/gdi/cairo_xlib_cairo.cxx
+++ b/vcl/unx/generic/gdi/cairo_xlib_cairo.cxx
@@ -235,6 +235,7 @@ namespace cairo
                                     &cairo_surface_destroy )));
     }
 
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> X11Surface::createVirtualDevice() const
     {
         SystemGraphicsData aSystemGraphicsData;
diff --git a/vcl/unx/gtk3/gtkcairo.cxx b/vcl/unx/gtk3/gtkcairo.cxx
index f389f4d087c1..2b2087be610c 100644
--- a/vcl/unx/gtk3/gtkcairo.cxx
+++ b/vcl/unx/gtk3/gtkcairo.cxx
@@ -113,6 +113,7 @@ namespace cairo
             mpGraphics->WidgetQueueDraw();
     }
 
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> Gtk3Surface::createVirtualDevice() const
     {
         SystemGraphicsData aSystemGraphicsData;
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index da42a85659d6..da7f4c6b8bcc 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -4487,6 +4487,7 @@ public:
         return rLabel.replaceAll("_", "__");
     }
 
+    // [-loplugin:scopedvclptr]
     virtual VclPtr<VirtualDevice> create_virtual_device() const override
     {
         // create with no separate alpha layer like everything sane does
@@ -4553,6 +4554,7 @@ public:
             gtk_container_resize_children(GTK_CONTAINER(m_pWidget));
 #endif
 
+        // [-loplugin:scopedvclptr]
         VclPtr<VirtualDevice> 
xOutput(VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA));
         xOutput->SetOutputSizePixel(aSize);
 
@@ -6680,6 +6682,7 @@ public:
             g_signal_handler_unblock(m_pWidget, 
m_nToplevelFocusChangedSignalId);
     }
 
+    // [-loplugin:scopedvclptr]
     virtual VclPtr<VirtualDevice> screenshot() override
     {
         // detect if we have to manually setup its size
@@ -23158,6 +23161,7 @@ public:
         return signal_custom_get_size(rOutput);
     }
 
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> create_render_virtual_device() const override
     {
         return create_virtual_device();
@@ -23613,6 +23617,7 @@ public:
         assert(false && "not implemented");
     }
 
+    // [-loplugin:scopedvclptr]
     VclPtr<VirtualDevice> create_render_virtual_device() const override
     {
         return create_virtual_device();

Reply via email to