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/SvxColorIconView.cxx                  |    1 
 svx/source/tbxctrls/tbxcolorupdate.cxx                    |    2 
 svx/source/unodraw/UnoGraphicExporter.cxx                 |    1 
 sw/source/core/doc/DocumentDeviceManager.cxx              |    2 
 vcl/source/app/salvtables.cxx                             |    2 
 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                                  |    4 
 17 files changed, 395 insertions(+)

New commits:
commit 2c518fbc6c4e70bdbaa26c602f498305c9770a4c
Author:     Andras Timar <[email protected]>
AuthorDate: Sat Feb 21 16:17:57 2026 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Fri Feb 27 15:34:59 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]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/200608
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/chart2/source/controller/dialogs/dlg_Theme.cxx 
b/chart2/source/controller/dialogs/dlg_Theme.cxx
index ea81a48b2218..af1985e4697e 100644
--- a/chart2/source/controller/dialogs/dlg_Theme.cxx
+++ b/chart2/source/controller/dialogs/dlg_Theme.cxx
@@ -78,6 +78,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 bebf679357bc..2d4af14feaa4 100644
--- a/chart2/source/controller/sidebar/ChartThemeControl.cxx
+++ b/chart2/source/controller/sidebar/ChartThemeControl.cxx
@@ -195,6 +195,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 71600c1e8c71..c8a1148067bf 100644
--- a/chart2/source/controller/sidebar/ChartThemePanel.cxx
+++ b/chart2/source/controller/sidebar/ChartThemePanel.cxx
@@ -95,6 +95,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 3546bb2a9308..6914c97d2af3 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -139,6 +139,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 ad8eed0a6878..03dc2cf498a0 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -382,6 +382,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 9a1dacbc5789..8f4616b454f5 100644
--- a/solenv/CompilerTest_compilerplugins_clang.mk
+++ b/solenv/CompilerTest_compilerplugins_clang.mk
@@ -79,6 +79,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/SvxColorIconView.cxx 
b/svx/source/tbxctrls/SvxColorIconView.cxx
index 96e102a14fd9..c26d24b08432 100644
--- a/svx/source/tbxctrls/SvxColorIconView.cxx
+++ b/svx/source/tbxctrls/SvxColorIconView.cxx
@@ -96,6 +96,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/tbxcolorupdate.cxx 
b/svx/source/tbxctrls/tbxcolorupdate.cxx
index 14879214a8e2..44dfca847e6f 100644
--- a/svx/source/tbxctrls/tbxcolorupdate.cxx
+++ b/svx/source/tbxctrls/tbxcolorupdate.cxx
@@ -193,6 +193,7 @@ void VclToolboxButtonColorUpdater::SetImage(VirtualDevice* 
pVirDev)
     mpTbx->SetItemImage(mnBtnId, Image(aGraphic.GetXGraphic()));
 }
 
+// [-loplugin:scopedvclptr]
 VclPtr<VirtualDevice> VclToolboxButtonColorUpdater::CreateVirtualDevice() const
 {
     auto xVD = VclPtr<VirtualDevice>::Create(*mpTbx->GetOutDev());
@@ -350,6 +351,7 @@ void ToolboxButtonColorUpdater::SetImage(VirtualDevice* 
pVirDev)
     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 799fe3af9bb3..398ced591d60 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 1d49f23e7182..d5cd71a38391 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/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx
index 26b3771eef00..0f76bc2173f7 100644
--- a/vcl/source/app/salvtables.cxx
+++ b/vcl/source/app/salvtables.cxx
@@ -665,6 +665,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
@@ -1678,6 +1679,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());
diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx
index 0334935e89cb..fc5616c3f8b6 100644
--- a/vcl/source/window/syswin.cxx
+++ b/vcl/source/window/syswin.cxx
@@ -1137,6 +1137,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 95e3bf834bed..300ab96536e1 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -4296,6 +4296,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
@@ -4362,6 +4363,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);
 
@@ -6571,6 +6573,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
@@ -6598,6 +6601,7 @@ public:
 #endif
         }
 
+        // [-loplugin:scopedvclptr]
         VclPtr<VirtualDevice> 
xOutput(VclPtr<VirtualDevice>::Create(DeviceFormat::WITHOUT_ALPHA));
         xOutput->SetOutputSizePixel(get_size());
         cairo_surface_t* pSurface = get_underlying_cairo_surface(*xOutput);

Reply via email to