cui/source/dialogs/srchxtra.cxx                         |   20 +-
 cui/source/options/optgdlg.cxx                          |    1 
 editeng/qa/unit/core-test.cxx                           |    1 
 editeng/source/editeng/editattr.cxx                     |    1 
 editeng/source/editeng/editdoc.cxx                      |    1 
 editeng/source/editeng/eerdll.cxx                       |    1 
 editeng/source/editeng/impedit2.cxx                     |    1 
 include/svl/itemset.hxx                                 |   18 ++
 include/svl/poolitem.hxx                                |   37 ----
 include/svl/voiditem.hxx                                |   53 ++++++
 include/svx/srchdlg.hxx                                 |   22 +-
 sfx2/source/appl/appbas.cxx                             |    1 
 sfx2/source/control/bindings.cxx                        |    1 
 sfx2/source/control/sfxstatuslistener.cxx               |    1 
 sfx2/source/control/shell.cxx                           |    1 
 sfx2/source/control/statcach.cxx                        |    1 
 sfx2/source/statbar/stbitem.cxx                         |    1 
 sfx2/source/toolbox/tbxitem.cxx                         |    1 
 sfx2/source/view/lokhelper.cxx                          |    2 
 starmath/source/view.cxx                                |    1 
 svl/Library_svl.mk                                      |    1 
 svl/qa/unit/items/test_itempool.cxx                     |    1 
 svl/source/items/itemset.cxx                            |  124 ++++++++++------
 svl/source/items/poolitem.cxx                           |   60 +++----
 svl/source/items/voiditem.cxx                           |   59 +++++++
 svx/source/dialog/srchdlg.cxx                           |   52 +++---
 svx/source/mnuctrls/clipboardctl.cxx                    |    1 
 svx/source/stbctrls/zoomctrl.cxx                        |    1 
 svx/source/svdraw/svdattr.cxx                           |    1 
 sw/qa/extras/tiledrendering/tiledrendering.cxx          |    1 
 sw/source/core/bastyp/init.cxx                          |    1 
 sw/source/core/doc/DocumentContentOperationsManager.cxx |    7 
 sw/source/uibase/app/apphdl.cxx                         |    1 
 sw/source/uibase/app/applab.cxx                         |    1 
 sw/source/uibase/lingu/olmenu.cxx                       |    1 
 sw/source/uibase/ribbar/workctrl.cxx                    |    1 
 vcl/source/app/svapp.cxx                                |   19 ++
 37 files changed, 341 insertions(+), 157 deletions(-)

New commits:
commit c351f920c426542f0d3685bb9df1363d3a6393f8
Author:     Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de>
AuthorDate: Mon Aug 14 18:21:13 2023 +0200
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Fri Aug 18 10:37:44 2023 +0200

    ITEM: preparations for more/easier changes
    
    This change is not about speed improvements but diverse
    preparations to make changes/reading/understanding easier.
    It does not change speed AFAIK.
    
    Added a global static debug-only counter to allow getting
    an overview over number of all allocated SfxPoolItem's
    and the still alloated ones at office shutdown. The values
    are used in Application::~Application to make a short info
    statement. It allows to be able to quickly detect if an
    error in future changes may lead to memory losses - these
    would show in dramaitically higher numbers then (hopefully)
    immediately.
    
    Moved SfxVoidItem to own source/header.
    
    Added container library interface support to SfxItemSet,
    adapted already some methods to use it - not all possible,
    I will commit & get status from gerrit 1st if all still works
    and then continue.
    
    Changed INVALID_POOL_ITEM from -1 to use a global unique
    incarnation of an isolated derivation from SfxPoolItem. It
    allows to avoid the (-1) pointer hack. Since still just
    pointers are compared it's not worse. NOTE: That way, more
    'special' SfxPoolItem's may be used for more States - a
    candidate is e.g. SfxVoidItem(0) which represents ::DISABLED
    state -- unfortunately not only, it is also used (mainly for
    UI stuff) with 'real' WhichIDs - hard to sort out, will have
    to stay that way for now AFAIK.
    
    Changed INVALID_POOL_ITEM stuff to use a static extern
    incarnated item in combination with a inline method
    to return it, called GetGlobalStaticInvalidItemInstance().
    
    Isolated create/cleanup of a SfxPoolItem entry in
    SfxItemSet to further modularize/simplify that. It is
    currently from constructor & destructor but already shows
    that PoolDefaults are handled differently - probably an
    error. Still, for now, do no change in behaviour (yet).
    
    Got regular 'killed by the Kill-Wrapper' messages from
    gerrit, seems to have to do with UITest_sw_findReplace.
    That python/c++ scripting stuff is hard to debug, but
    finally I identified the problem has to do with
    the INVALID_POOL_ITEM change. It was in
    SfxItemSet::InvalidateAllItems() where still a (-1)
    was used -> chaos in detecting invalid items.
    
    Change-Id: I595e1f25ab660c35c4f2d19c233d1dfadfe25214
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155675
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/cui/source/dialogs/srchxtra.cxx b/cui/source/dialogs/srchxtra.cxx
index 9ed00b46377d..4c672b9839f2 100644
--- a/cui/source/dialogs/srchxtra.cxx
+++ b/cui/source/dialogs/srchxtra.cxx
@@ -135,7 +135,7 @@ 
SvxSearchAttributeDialog::SvxSearchAttributeDialog(weld::Window* pParent,
                     if ( nSlot == rList[i].nSlot )
                     {
                         bFound = true;
-                        if ( IsInvalidItem( rList[i].pItem ) )
+                        if ( IsInvalidItem( rList[i].pItemPtr ) )
                             bChecked = true;
                     }
                 }
@@ -167,8 +167,8 @@ SvxSearchAttributeDialog::~SvxSearchAttributeDialog()
 
 IMPL_LINK_NOARG(SvxSearchAttributeDialog, OKHdl, weld::Button&, void)
 {
-    SearchAttrItem aInvalidItem;
-    aInvalidItem.pItem = INVALID_POOL_ITEM;
+    SearchAttrInfo aInvalidItem;
+    aInvalidItem.pItemPtr = INVALID_POOL_ITEM;
 
     for (int i = 0, nCount = m_xAttrLB->n_children(); i < nCount; ++i)
     {
@@ -178,17 +178,17 @@ IMPL_LINK_NOARG(SvxSearchAttributeDialog, OKHdl, 
weld::Button&, void)
         sal_uInt16 j;
         for ( j = rList.Count(); j; )
         {
-            SearchAttrItem& rItem = rList[ --j ];
+            SearchAttrInfo& rItem = rList[ --j ];
             if( rItem.nSlot == nSlot )
             {
                 if( bChecked )
                 {
-                    if( !IsInvalidItem( rItem.pItem ) )
-                        delete rItem.pItem;
-                    rItem.pItem = INVALID_POOL_ITEM;
+                    if( !IsInvalidItem( rItem.pItemPtr ) )
+                        delete rItem.pItemPtr;
+                    rItem.pItemPtr = INVALID_POOL_ITEM;
                 }
-                else if( IsInvalidItem( rItem.pItem ) )
-                    rItem.pItem = nullptr;
+                else if( IsInvalidItem( rItem.pItemPtr ) )
+                    rItem.pItemPtr = nullptr;
                 j = 1;
                 break;
             }
@@ -203,7 +203,7 @@ IMPL_LINK_NOARG(SvxSearchAttributeDialog, OKHdl, 
weld::Button&, void)
 
     // remove invalid items (pItem == NULL)
     for ( sal_uInt16 n = rList.Count(); n; )
-        if ( !rList[ --n ].pItem )
+        if ( !rList[ --n ].pItemPtr )
             rList.Remove( n );
 
     m_xDialog->response(RET_OK);
diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
index 64d11a62451b..3223637b8d47 100644
--- a/cui/source/options/optgdlg.cxx
+++ b/cui/source/options/optgdlg.cxx
@@ -48,6 +48,7 @@
 #include <editeng/editids.hrc>
 #include <svx/svxids.hrc>
 #include <svl/intitem.hxx>
+#include <svl/voiditem.hxx>
 #include <GraphicsTestsDialog.hxx>
 #include <unotools/searchopt.hxx>
 #include <sal/log.hxx>
diff --git a/editeng/qa/unit/core-test.cxx b/editeng/qa/unit/core-test.cxx
index 075703266c18..d3f92ce60c2c 100644
--- a/editeng/qa/unit/core-test.cxx
+++ b/editeng/qa/unit/core-test.cxx
@@ -29,6 +29,7 @@
 #include <editeng/flditem.hxx>
 #include <editeng/udlnitem.hxx>
 #include <svl/srchitem.hxx>
+#include <svl/voiditem.hxx>
 #include <editeng/fontitem.hxx>
 #include <editeng/fhgtitem.hxx>
 
diff --git a/editeng/source/editeng/editattr.cxx 
b/editeng/source/editeng/editattr.cxx
index a045f16ade81..d1d79fd0263e 100644
--- a/editeng/source/editeng/editattr.cxx
+++ b/editeng/source/editeng/editattr.cxx
@@ -20,6 +20,7 @@
 #include <vcl/outdev.hxx>
 
 #include <svl/grabbagitem.hxx>
+#include <svl/voiditem.hxx>
 #include <libxml/xmlwriter.h>
 #include <editeng/svxfont.hxx>
 #include <editeng/flditem.hxx>
diff --git a/editeng/source/editeng/editdoc.cxx 
b/editeng/source/editeng/editdoc.cxx
index d4dc4ee16e37..9b0d3948bc13 100644
--- a/editeng/source/editeng/editdoc.cxx
+++ b/editeng/source/editeng/editdoc.cxx
@@ -54,6 +54,7 @@
 #include <osl/diagnose.h>
 
 #include <svl/grabbagitem.hxx>
+#include <svl/voiditem.hxx>
 #include <tools/debug.hxx>
 #include <com/sun/star/i18n/ScriptType.hpp>
 #include <libxml/xmlwriter.h>
diff --git a/editeng/source/editeng/eerdll.cxx 
b/editeng/source/editeng/eerdll.cxx
index f6a1cbc049c2..9e3e8c4cf8c5 100644
--- a/editeng/source/editeng/eerdll.cxx
+++ b/editeng/source/editeng/eerdll.cxx
@@ -36,6 +36,7 @@
 #include <editeng/hngpnctitem.hxx>
 #include <editeng/forbiddenruleitem.hxx>
 #include <svl/grabbagitem.hxx>
+#include <svl/voiditem.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/virdev.hxx>
 
diff --git a/editeng/source/editeng/impedit2.cxx 
b/editeng/source/editeng/impedit2.cxx
index 8d4960069cc8..61b3d0062748 100644
--- a/editeng/source/editeng/impedit2.cxx
+++ b/editeng/source/editeng/impedit2.cxx
@@ -59,6 +59,7 @@
 #include <sot/exchange.hxx>
 #include <sot/formats.hxx>
 #include <svl/asiancfg.hxx>
+#include <svl/voiditem.hxx>
 #include <i18nutil/unicode.hxx>
 #include <comphelper/diagnose_ex.hxx>
 #include <comphelper/flagguard.hxx>
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index a3736427b002..37141a0a79b3 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -57,6 +57,21 @@ protected:
     void setCallback(const std::function<void(const SfxPoolItem*, const 
SfxPoolItem*)> &func) { m_aCallback = func; }
     void clearCallback() { m_aCallback = nullptr; }
 
+    // container library interface support
+    // only for internal use (for now), thus protected
+    using const_iterator = SfxPoolItem const**;
+
+    const_iterator begin() const noexcept { return m_ppItems; }
+    const_iterator end() const noexcept { return begin() + m_nTotalCount; }
+
+    bool empty() const noexcept { return 0 == m_nTotalCount; }
+    sal_Int32 size() const noexcept { return m_nTotalCount; }
+    SfxPoolItem const* operator[](sal_Int32 idx) const noexcept
+    {
+        assert(idx >= 0 && idx < m_nTotalCount && "index out of range");
+        return m_ppItems[idx];
+    }
+
 friend class SfxItemPoolCache;
 friend class SfxAllItemSet;
 
@@ -242,6 +257,9 @@ private:
     // split version(s) of GetItemStateImpl for input types WhichID and Offset
     SfxItemState GetItemState_ForWhichID( SfxItemState eState, sal_uInt16 
nWhich, bool bSrchInParent, const SfxPoolItem **ppItem) const;
     SfxItemState GetItemState_ForOffset( sal_uInt16 nOffset, const SfxPoolItem 
**ppItem) const;
+
+    void implCreateItemEntry(SfxPoolItem const*& rpTarget, SfxPoolItem const* 
pSource);
+    void implCleanupItemEntry(SfxPoolItem const* pSource);
 };
 
 inline void SfxItemSet::SetParent( const SfxItemSet* pNew )
diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx
index 10a7901b4e70..46dd8b0a76f5 100644
--- a/include/svl/poolitem.hxx
+++ b/include/svl/poolitem.hxx
@@ -106,7 +106,10 @@ enum class SfxItemState {
     SET      = 0x0040
 };
 
-#define INVALID_POOL_ITEM reinterpret_cast<SfxPoolItem*>(-1)
+#ifdef DBG_UTIL
+SVL_DLLPUBLIC size_t getAllocatedSfxPoolItemCount();
+SVL_DLLPUBLIC size_t getUsedSfxPoolItemCount();
+#endif
 
 class SfxItemPool;
 class SfxItemSet;
@@ -118,7 +121,6 @@ friend class SfxItemPool;
 friend class SfxItemDisruptor_Impl;
 friend class SfxItemPoolCache;
 friend class SfxItemSet;
-friend class SfxVoidItem;
 
     mutable sal_uInt32 m_nRefCount;
     sal_uInt16  m_nWhich;
@@ -286,40 +288,13 @@ inline bool IsPooledItem( const SfxPoolItem *pItem )
     return pItem && pItem->GetRefCount() > 0 && pItem->GetRefCount() <= 
SFX_ITEMS_MAXREF;
 }
 
+SVL_DLLPUBLIC extern SfxPoolItem const * const INVALID_POOL_ITEM;
+
 inline bool IsInvalidItem(const SfxPoolItem *pItem)
 {
     return pItem == INVALID_POOL_ITEM;
 }
 
-class SVL_DLLPUBLIC SfxVoidItem final: public SfxPoolItem
-{
-public:
-                            static SfxPoolItem* CreateDefault();
-                            explicit SfxVoidItem( sal_uInt16 nWhich );
-                            virtual ~SfxVoidItem() override;
-
-    SfxVoidItem(SfxVoidItem const &) = default;
-    SfxVoidItem(SfxVoidItem &&) = default;
-    SfxVoidItem & operator =(SfxVoidItem const &) = delete; // due to 
SfxPoolItem
-    SfxVoidItem & operator =(SfxVoidItem &&) = delete; // due to SfxPoolItem
-
-    virtual bool            operator==( const SfxPoolItem& ) const override;
-
-    virtual bool GetPresentation( SfxItemPresentation ePres,
-                                    MapUnit eCoreMetric,
-                                    MapUnit ePresMetric,
-                                    OUString &rText,
-                                    const IntlWrapper& ) const override;
-    virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
-
-    // create a copy of itself
-    virtual SfxVoidItem*    Clone( SfxItemPool *pPool = nullptr ) const 
override;
-
-    /** Always returns true as this is an SfxVoidItem. */
-    virtual bool            IsVoidItem() const override;
-};
-
-
 class SVL_DLLPUBLIC SfxPoolItemHint final : public SfxHint
 {
     SfxPoolItem* pObj;
diff --git a/include/svl/voiditem.hxx b/include/svl/voiditem.hxx
new file mode 100644
index 000000000000..b06f28e84b2e
--- /dev/null
+++ b/include/svl/voiditem.hxx
@@ -0,0 +1,53 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SVL_VOIDITEM_HXX
+#define INCLUDED_SVL_VOIDITEM_HXX
+
+#include <svl/poolitem.hxx>
+
+class SVL_DLLPUBLIC SfxVoidItem final : public SfxPoolItem
+{
+public:
+    static SfxPoolItem* CreateDefault();
+    explicit SfxVoidItem(sal_uInt16 nWhich);
+    virtual ~SfxVoidItem() override;
+
+    SfxVoidItem(SfxVoidItem const&) = default;
+    SfxVoidItem(SfxVoidItem&&) = default;
+    SfxVoidItem& operator=(SfxVoidItem const&) = delete; // due to SfxPoolItem
+    SfxVoidItem& operator=(SfxVoidItem&&) = delete; // due to SfxPoolItem
+
+    virtual bool operator==(const SfxPoolItem&) const override;
+
+    virtual bool GetPresentation(SfxItemPresentation ePres, MapUnit 
eCoreMetric,
+                                 MapUnit ePresMetric, OUString& rText,
+                                 const IntlWrapper&) const override;
+    virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
+
+    // create a copy of itself
+    virtual SfxVoidItem* Clone(SfxItemPool* pPool = nullptr) const override;
+
+    /** Always returns true as this is an SfxVoidItem. */
+    virtual bool IsVoidItem() const override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/srchdlg.hxx b/include/svx/srchdlg.hxx
index 2b975e435083..9a75199ad818 100644
--- a/include/svx/srchdlg.hxx
+++ b/include/svx/srchdlg.hxx
@@ -38,15 +38,15 @@ struct SearchDlg_Impl;
 enum class ModifyFlags;
 enum class TransliterationFlags;
 
-struct SearchAttrItem
+struct SearchAttrInfo
 {
     sal_uInt16          nSlot;
-    SfxPoolItem*    pItem;
+    const SfxPoolItem*  pItemPtr;
 };
 
-typedef std::vector<SearchAttrItem> SrchAttrItemList;
+typedef std::vector<SearchAttrInfo> SrchAttrInfoList;
 
-class SVX_DLLPUBLIC SearchAttrItemList : private SrchAttrItemList
+class SVX_DLLPUBLIC SearchAttrItemList : private SrchAttrInfoList
 {
 public:
     SearchAttrItemList() {}
@@ -57,15 +57,15 @@ public:
     void            Put( const SfxItemSet& rSet );
     SfxItemSet&     Get( SfxItemSet& rSet );
     void            Clear();
-    sal_uInt16      Count() const { return SrchAttrItemList::size(); }
-    SearchAttrItem& operator[](sal_uInt16 nPos)
-                        { return SrchAttrItemList::operator[]( nPos ); }
-    SearchAttrItem& GetObject( sal_uInt16 nPos )
-                        { return SrchAttrItemList::operator[]( nPos ); }
+    sal_uInt16      Count() const { return SrchAttrInfoList::size(); }
+    SearchAttrInfo& operator[](sal_uInt16 nPos)
+                        { return SrchAttrInfoList::operator[]( nPos ); }
+    SearchAttrInfo& GetObject( sal_uInt16 nPos )
+                        { return SrchAttrInfoList::operator[]( nPos ); }
 
     // the pointer to the item is not being copied, so don't delete
-    void Insert( const SearchAttrItem& rItem )
-        { SrchAttrItemList::push_back( rItem ); }
+    void Insert( const SearchAttrInfo& rItem )
+        { SrchAttrInfoList::push_back( rItem ); }
     // deletes the pointer to the items
     void Remove(size_t nPos);
 };
diff --git a/sfx2/source/appl/appbas.cxx b/sfx2/source/appl/appbas.cxx
index 482b93692200..1cedcd978540 100644
--- a/sfx2/source/appl/appbas.cxx
+++ b/sfx2/source/appl/appbas.cxx
@@ -28,6 +28,7 @@
 #include <svl/intitem.hxx>
 #include <svl/eitem.hxx>
 #include <svl/whiter.hxx>
+#include <svl/voiditem.hxx>
 #include <basic/sbstar.hxx>
 
 #include <sfx2/frame.hxx>
diff --git a/sfx2/source/control/bindings.cxx b/sfx2/source/control/bindings.cxx
index 629ad3aa41df..dcba259627ab 100644
--- a/sfx2/source/control/bindings.cxx
+++ b/sfx2/source/control/bindings.cxx
@@ -29,6 +29,7 @@
 #include <svl/eitem.hxx>
 #include <svl/intitem.hxx>
 #include <svl/stritem.hxx>
+#include <svl/voiditem.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/timer.hxx>
 #include <com/sun/star/frame/XDispatch.hpp>
diff --git a/sfx2/source/control/sfxstatuslistener.cxx 
b/sfx2/source/control/sfxstatuslistener.cxx
index 7cc4e8dd688b..b7e76cdff7c3 100644
--- a/sfx2/source/control/sfxstatuslistener.cxx
+++ b/sfx2/source/control/sfxstatuslistener.cxx
@@ -23,6 +23,7 @@
 #include <svl/stritem.hxx>
 #include <svl/intitem.hxx>
 #include <svl/visitem.hxx>
+#include <svl/voiditem.hxx>
 #include <comphelper/processfactory.hxx>
 #include <comphelper/servicehelper.hxx>
 #include <vcl/svapp.hxx>
diff --git a/sfx2/source/control/shell.cxx b/sfx2/source/control/shell.cxx
index aeba636a491f..5cba99c231d5 100644
--- a/sfx2/source/control/shell.cxx
+++ b/sfx2/source/control/shell.cxx
@@ -25,6 +25,7 @@
 #include <osl/diagnose.h>
 #include <svl/itempool.hxx>
 #include <svl/setitem.hxx>
+#include <svl/voiditem.hxx>
 #include <svl/undo.hxx>
 #include <itemdel.hxx>
 #include <svtools/asynclink.hxx>
diff --git a/sfx2/source/control/statcach.cxx b/sfx2/source/control/statcach.cxx
index 03f1daa5a370..cf059affbed1 100644
--- a/sfx2/source/control/statcach.cxx
+++ b/sfx2/source/control/statcach.cxx
@@ -31,6 +31,7 @@
 #include <svl/intitem.hxx>
 #include <svl/stritem.hxx>
 #include <svl/visitem.hxx>
+#include <svl/voiditem.hxx>
 
 #include <sfx2/app.hxx>
 #include <statcach.hxx>
diff --git a/sfx2/source/statbar/stbitem.cxx b/sfx2/source/statbar/stbitem.cxx
index e9d8512fa832..2387557d6ba9 100644
--- a/sfx2/source/statbar/stbitem.cxx
+++ b/sfx2/source/statbar/stbitem.cxx
@@ -18,6 +18,7 @@
  */
 
 #include <svl/stritem.hxx>
+#include <svl/voiditem.hxx>
 #include <com/sun/star/util/URL.hpp>
 #include <com/sun/star/util/URLTransformer.hpp>
 #include <com/sun/star/util/XURLTransformer.hpp>
diff --git a/sfx2/source/toolbox/tbxitem.cxx b/sfx2/source/toolbox/tbxitem.cxx
index 70bd2b2762de..f355806aaa00 100644
--- a/sfx2/source/toolbox/tbxitem.cxx
+++ b/sfx2/source/toolbox/tbxitem.cxx
@@ -39,6 +39,7 @@
 #include <svl/stritem.hxx>
 #include <svl/intitem.hxx>
 #include <svl/visitem.hxx>
+#include <svl/voiditem.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/toolbox.hxx>
 
diff --git a/sfx2/source/view/lokhelper.cxx b/sfx2/source/view/lokhelper.cxx
index 524bf7f7efda..a6d9ef825e35 100644
--- a/sfx2/source/view/lokhelper.cxx
+++ b/sfx2/source/view/lokhelper.cxx
@@ -558,7 +558,7 @@ namespace {
 
 void SfxLokHelper::sendUnoStatus(const SfxViewShell* pShell, const 
SfxPoolItem* pItem)
 {
-    if (!pShell || !pItem || pItem == INVALID_POOL_ITEM || 
DisableCallbacks::disabled())
+    if (!pShell || !pItem || IsInvalidItem(pItem) || 
DisableCallbacks::disabled())
         return;
 
     boost::property_tree::ptree aItem = pItem->dumpAsJSON();
diff --git a/starmath/source/view.cxx b/starmath/source/view.cxx
index e495039326f9..1a1a236deca5 100644
--- a/starmath/source/view.cxx
+++ b/starmath/source/view.cxx
@@ -55,6 +55,7 @@
 #include <svl/itemset.hxx>
 #include <svl/poolitem.hxx>
 #include <svl/stritem.hxx>
+#include <svl/voiditem.hxx>
 #include <vcl/transfer.hxx>
 #include <svtools/colorcfg.hxx>
 #include <svl/whiter.hxx>
diff --git a/svl/Library_svl.mk b/svl/Library_svl.mk
index 87024bbf499e..aee540d56514 100644
--- a/svl/Library_svl.mk
+++ b/svl/Library_svl.mk
@@ -143,6 +143,7 @@ $(eval $(call gb_Library_add_exception_objects,svl,\
     svl/source/items/style \
     svl/source/items/stylepool \
     svl/source/items/visitem \
+    svl/source/items/voiditem \
     svl/source/items/whiter \
     svl/source/misc/PasswordHelper \
     svl/source/misc/adrparse \
diff --git a/svl/qa/unit/items/test_itempool.cxx 
b/svl/qa/unit/items/test_itempool.cxx
index 6868999f0f76..339da002bfc1 100644
--- a/svl/qa/unit/items/test_itempool.cxx
+++ b/svl/qa/unit/items/test_itempool.cxx
@@ -8,6 +8,7 @@
  */
 
 #include <svl/itempool.hxx>
+#include <svl/voiditem.hxx>
 #include <poolio.hxx>
 
 #include <cppunit/TestAssert.h>
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 289a69adf4da..401044e8ba09 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -32,6 +32,7 @@
 #include <svl/itemiter.hxx>
 #include <svl/setitem.hxx>
 #include <svl/whiter.hxx>
+#include <svl/voiditem.hxx>
 
 #include <items_helper.hxx>
 
@@ -99,6 +100,68 @@ SfxItemSet::SfxItemSet(SfxItemPool& pool, 
WhichRangesContainer wids)
     assert(svl::detail::validRanges2(m_pWhichRanges));
 }
 
+void SfxItemSet::implCreateItemEntry(SfxPoolItem const*& rpTarget, SfxPoolItem 
const* pSource)
+{
+    if (nullptr == pSource
+        || IsInvalidItem(pSource)
+        || IsStaticDefaultItem(pSource))
+    {
+        // copy the pointer if
+        // - SfxItemState::UNKNOWN aka current default (nullptr)
+        // - SfxItemState::DONTCARE aka invalid item
+        // - StaticDefaultItem aka static pool default (however this finds
+        //   it's way to the ItemSet? It *should* be default, too)
+        rpTarget = pSource;
+        return;
+    }
+
+    if (0 == pSource->Which())
+    {
+        // these *should* be SfxVoidItem(0) the only Items with 0 == WhichID
+        rpTarget = pSource->Clone();
+        return;
+    }
+
+    if (m_pPool->IsItemPoolable(*pSource))
+    {
+        // copy the pointer and increase RefCount
+        rpTarget = pSource;
+        rpTarget->AddRef();
+        return;
+    }
+
+    // !IsPoolable() => assign via Pool
+    rpTarget = &m_pPool->Put(*pSource);
+}
+
+void SfxItemSet::implCleanupItemEntry(SfxPoolItem const* pSource)
+{
+    if (nullptr == pSource         // no entry, done
+        || IsInvalidItem(pSource)  // nothing to do for invalid item entries
+        || IsDefaultItem(pSource)) // default items are owned by the pool, 
nothing to do
+    {
+        return;
+    }
+
+    if (0 == pSource->Which())
+    {
+        // these *should* be SfxVoidItem(0) the only Items with 0 == WhichID
+        // and need to be deleted
+        delete pSource;
+        return;
+    }
+
+    if (1 < pSource->GetRefCount())
+    {
+        // Still multiple references present, so just alter the RefCount
+        pSource->ReleaseRef();
+        return;
+    }
+
+    // Delete from Pool
+    m_pPool->Remove(*pSource);
+}
+
 SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
     : m_pPool( rASet.m_pPool )
     , m_pParent( rASet.m_pParent )
@@ -114,28 +177,17 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
         return;
     }
 
-    m_ppItems = new const SfxPoolItem* [TotalCount()] {};
+    // allocate new array (no need to initialize, will be done below)
+    m_ppItems = new const SfxPoolItem* [TotalCount()];
 
     // Copy attributes
-    SfxPoolItem const** ppDst = m_ppItems;
-    SfxPoolItem const** ppSrc = rASet.m_ppItems;
-    for( sal_uInt16 n = TotalCount(); n; --n, ++ppDst, ++ppSrc )
-        if ( nullptr == *ppSrc ||                 // Current Default?
-             IsInvalidItem(*ppSrc) ||       // DontCare?
-             IsStaticDefaultItem(*ppSrc) )  // Defaults that are not to be 
pooled?
-            // Just copy the pointer
-            *ppDst = *ppSrc;
-        else if (m_pPool->IsItemPoolable( **ppSrc ))
-        {
-            // Just copy the pointer and increase RefCount
-            *ppDst = *ppSrc;
-            (*ppDst)->AddRef();
-        }
-        else if ( !(*ppSrc)->Which() )
-            *ppDst = (*ppSrc)->Clone();
-        else
-            // !IsPoolable() => assign via Pool
-            *ppDst = &m_pPool->Put( **ppSrc );
+    SfxPoolItem const** ppDst(m_ppItems);
+
+    for (const auto& rSource : rASet)
+    {
+        implCreateItemEntry(*ppDst, rSource);
+        ppDst++;
+    }
 
     assert(svl::detail::validRanges2(m_pWhichRanges));
 }
@@ -170,32 +222,24 @@ SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept
 
 SfxItemSet::~SfxItemSet()
 {
-    if (!m_pWhichRanges.empty()) // might be nullptr if we have been moved-from
+    // might be nullptr if we have been moved-from, also only needed
+    // when we have ::SET items
+    if (!m_pWhichRanges.empty() && Count())
     {
-        if( Count() )
+        for (auto& rCandidate : *this)
         {
-            SfxPoolItem const** ppFnd = m_ppItems;
-            for( sal_uInt16 nCnt = TotalCount(); nCnt; --nCnt, ++ppFnd )
-                if( *ppFnd && !IsInvalidItem(*ppFnd) )
-                {
-                    if( !(*ppFnd)->Which() )
-                        delete *ppFnd;
-                    else {
-                        // Still multiple references present, so just alter 
the RefCount
-                        if ( 1 < (*ppFnd)->GetRefCount() && 
!IsDefaultItem(*ppFnd) )
-                            (*ppFnd)->ReleaseRef();
-                        else
-                            if ( !IsDefaultItem(*ppFnd) )
-                                // Delete from Pool
-                                m_pPool->Remove( **ppFnd );
-                    }
-                }
+            implCleanupItemEntry(rCandidate);
         }
     }
 
     if (!m_bItemsFixed)
+    {
+        // free SfxPoolItem array
         delete[] m_ppItems;
-    m_pWhichRanges.reset(); // for invariant-testing
+    }
+
+    // for invariant-testing
+    m_pWhichRanges.reset();
 }
 
 /**
@@ -316,7 +360,7 @@ void SfxItemSet::ClearInvalidItems()
 void SfxItemSet::InvalidateAllItems()
 {
     assert( !m_nCount && "There are still Items set" );
-    memset(static_cast<void*>(m_ppItems), -1, TotalCount() * 
sizeof(SfxPoolItem*));
+    std::fill(m_ppItems, m_ppItems + TotalCount(), INVALID_POOL_ITEM);
 }
 
 SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich,
diff --git a/svl/source/items/poolitem.cxx b/svl/source/items/poolitem.cxx
index cb1bec15159c..9a45e8803448 100644
--- a/svl/source/items/poolitem.cxx
+++ b/svl/source/items/poolitem.cxx
@@ -461,16 +461,30 @@
 // class SwPaMItem : public SfxPoolItem
 //////////////////////////////////////////////////////////////////////////////
 
+#ifdef DBG_UTIL
+static size_t nAllocatedSfxPoolItemCount(0);
+static size_t nUsedSfxPoolItemCount(0);
+size_t getAllocatedSfxPoolItemCount() { return nAllocatedSfxPoolItemCount; }
+size_t getUsedSfxPoolItemCount() { return nUsedSfxPoolItemCount; }
+#endif
+
 SfxPoolItem::SfxPoolItem(sal_uInt16 const nWhich)
     : m_nRefCount(0)
     , m_nWhich(nWhich)
     , m_nKind(SfxItemKind::NONE)
 {
+#ifdef DBG_UTIL
+    nAllocatedSfxPoolItemCount++;
+    nUsedSfxPoolItemCount++;
+#endif
     assert(nWhich <= SHRT_MAX);
 }
 
 SfxPoolItem::~SfxPoolItem()
 {
+#ifdef DBG_UTIL
+    nAllocatedSfxPoolItemCount--;
+#endif
     assert((m_nRefCount == 0 || m_nRefCount > SFX_ITEMS_MAXREF) && "destroying 
item in use");
 }
 
@@ -562,40 +576,6 @@ std::unique_ptr<SfxPoolItem> 
SfxPoolItem::CloneSetWhich(sal_uInt16 nNewWhich) co
 
 bool SfxPoolItem::IsVoidItem() const { return false; }
 
-SfxPoolItem* SfxVoidItem::CreateDefault() { return new SfxVoidItem(0); }
-
-SfxVoidItem::SfxVoidItem(sal_uInt16 which)
-    : SfxPoolItem(which)
-{
-}
-
-bool SfxVoidItem::operator==(const SfxPoolItem& rCmp) const
-{
-    assert(SfxPoolItem::operator==(rCmp));
-    (void)rCmp;
-    return true;
-}
-
-bool SfxVoidItem::GetPresentation(SfxItemPresentation /*ePresentation*/, 
MapUnit /*eCoreMetric*/,
-                                  MapUnit /*ePresentationMetric*/, OUString& 
rText,
-                                  const IntlWrapper&) const
-{
-    rText = "Void";
-    return true;
-}
-
-void SfxVoidItem::dumpAsXml(xmlTextWriterPtr pWriter) const
-{
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxVoidItem"));
-    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"),
-                                      
BAD_CAST(OString::number(Which()).getStr()));
-    (void)xmlTextWriterEndElement(pWriter);
-}
-
-SfxVoidItem* SfxVoidItem::Clone(SfxItemPool*) const { return new 
SfxVoidItem(*this); }
-
-bool SfxVoidItem::IsVoidItem() const { return true; }
-
 void SfxPoolItem::ScaleMetrics(tools::Long /*lMult*/, tools::Long /*lDiv*/) {}
 
 bool SfxPoolItem::HasMetrics() const { return false; }
@@ -612,6 +592,16 @@ bool SfxPoolItem::PutValue(const css::uno::Any&, sal_uInt8)
     return false;
 }
 
-SfxVoidItem::~SfxVoidItem() {}
+namespace
+{
+class InvalidItem final : public SfxPoolItem
+{
+    virtual bool operator==(const SfxPoolItem&) const override { return true; }
+    virtual SfxPoolItem* Clone(SfxItemPool*) const override { return nullptr; }
+};
+InvalidItem aInvalidItem;
+}
+
+SfxPoolItem const* const INVALID_POOL_ITEM = &aInvalidItem;
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/voiditem.cxx b/svl/source/items/voiditem.cxx
new file mode 100644
index 000000000000..3afa64de5332
--- /dev/null
+++ b/svl/source/items/voiditem.cxx
@@ -0,0 +1,59 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svl/voiditem.hxx>
+#include <libxml/xmlwriter.h>
+
+SfxPoolItem* SfxVoidItem::CreateDefault() { return new SfxVoidItem(0); }
+
+SfxVoidItem::SfxVoidItem(sal_uInt16 which)
+    : SfxPoolItem(which)
+{
+}
+
+bool SfxVoidItem::operator==(const SfxPoolItem& rCmp) const
+{
+    assert(SfxPoolItem::operator==(rCmp));
+    (void)rCmp;
+    return true;
+}
+
+bool SfxVoidItem::GetPresentation(SfxItemPresentation /*ePresentation*/, 
MapUnit /*eCoreMetric*/,
+                                  MapUnit /*ePresentationMetric*/, OUString& 
rText,
+                                  const IntlWrapper&) const
+{
+    rText = "Void";
+    return true;
+}
+
+void SfxVoidItem::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxVoidItem"));
+    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"),
+                                      
BAD_CAST(OString::number(Which()).getStr()));
+    (void)xmlTextWriterEndElement(pWriter);
+}
+
+SfxVoidItem* SfxVoidItem::Clone(SfxItemPool*) const { return new 
SfxVoidItem(*this); }
+
+bool SfxVoidItem::IsVoidItem() const { return true; }
+
+SfxVoidItem::~SfxVoidItem() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/dialog/srchdlg.cxx b/svx/source/dialog/srchdlg.cxx
index 7f496535e2b7..dcb467b5475f 100644
--- a/svx/source/dialog/srchdlg.cxx
+++ b/svx/source/dialog/srchdlg.cxx
@@ -175,19 +175,19 @@ static void StrArrToList_Impl( 
TypedWhichId<SfxStringListItem> nId, const std::v
 }
 
 SearchAttrItemList::SearchAttrItemList( SearchAttrItemList&& rList ) :
-    SrchAttrItemList(std::move(rList))
+    SrchAttrInfoList(std::move(rList))
 {
     for ( size_t i = 0; i < size(); ++i )
-        if ( !IsInvalidItem( (*this)[i].pItem ) )
-            (*this)[i].pItem = (*this)[i].pItem->Clone();
+        if ( !IsInvalidItem( (*this)[i].pItemPtr ) )
+            (*this)[i].pItemPtr = (*this)[i].pItemPtr->Clone();
 }
 
 SearchAttrItemList::SearchAttrItemList( const SearchAttrItemList& rList ) :
-    SrchAttrItemList(rList)
+    SrchAttrInfoList(rList)
 {
     for ( size_t i = 0; i < size(); ++i )
-        if ( !IsInvalidItem( (*this)[i].pItem ) )
-            (*this)[i].pItem = (*this)[i].pItem->Clone();
+        if ( !IsInvalidItem( (*this)[i].pItemPtr ) )
+            (*this)[i].pItemPtr = (*this)[i].pItemPtr->Clone();
 }
 
 SearchAttrItemList::~SearchAttrItemList()
@@ -202,7 +202,7 @@ void SearchAttrItemList::Put( const SfxItemSet& rSet )
 
     SfxItemPool* pPool = rSet.GetPool();
     SfxItemIter aIter( rSet );
-    SearchAttrItem aItem;
+    SearchAttrInfo aItem;
     const SfxPoolItem* pItem = aIter.GetCurItem();
     sal_uInt16 nWhich;
 
@@ -212,12 +212,12 @@ void SearchAttrItemList::Put( const SfxItemSet& rSet )
         if( IsInvalidItem( pItem ) )
         {
             nWhich = rSet.GetWhichByOffset( aIter.GetCurPos() );
-            aItem.pItem = const_cast<SfxPoolItem*>(pItem);
+            aItem.pItemPtr = pItem;
         }
         else
         {
             nWhich = pItem->Which();
-            aItem.pItem = pItem->Clone();
+            aItem.pItemPtr = pItem->Clone();
         }
 
         aItem.nSlot = pPool->GetSlotId( nWhich );
@@ -233,10 +233,10 @@ SfxItemSet& SearchAttrItemList::Get( SfxItemSet& rSet )
     SfxItemPool* pPool = rSet.GetPool();
 
     for ( size_t i = 0; i < size(); ++i )
-        if ( IsInvalidItem( (*this)[i].pItem ) )
+        if ( IsInvalidItem( (*this)[i].pItemPtr ) )
             rSet.InvalidateItem( pPool->GetWhich( (*this)[i].nSlot ) );
         else
-            rSet.Put( *(*this)[i].pItem );
+            rSet.Put( *(*this)[i].pItemPtr );
     return rSet;
 }
 
@@ -244,9 +244,9 @@ SfxItemSet& SearchAttrItemList::Get( SfxItemSet& rSet )
 void SearchAttrItemList::Clear()
 {
     for ( size_t i = 0; i < size(); ++i )
-        if ( !IsInvalidItem( (*this)[i].pItem ) )
-            delete (*this)[i].pItem;
-    SrchAttrItemList::clear();
+        if ( !IsInvalidItem( (*this)[i].pItemPtr ) )
+            delete (*this)[i].pItemPtr;
+    SrchAttrInfoList::clear();
 }
 
 
@@ -258,10 +258,10 @@ void SearchAttrItemList::Remove(size_t nPos)
         nLen = size() - nPos;
 
     for ( size_t i = nPos; i < nPos + nLen; ++i )
-        if ( !IsInvalidItem( (*this)[i].pItem ) )
-            delete (*this)[i].pItem;
+        if ( !IsInvalidItem( (*this)[i].pItemPtr ) )
+            delete (*this)[i].pItemPtr;
 
-    SrchAttrItemList::erase( begin() + nPos, begin() + nPos + nLen );
+    SrchAttrInfoList::erase( begin() + nPos, begin() + nPos + nLen );
 }
 
 SvxSearchDialog::SvxSearchDialog(weld::Window* pParent, SfxChildWindow* 
pChildWin, SfxBindings& rBind)
@@ -1996,14 +1996,14 @@ IMPL_LINK_NOARG(SvxSearchDialog, FormatHdl_Impl, 
weld::Button&, void)
     const SfxPoolItem* pItem;
     for( sal_uInt16 n = 0; n < pList->Count(); ++n )
     {
-        SearchAttrItem* pAItem = &pList->GetObject(n);
-        if( !IsInvalidItem( pAItem->pItem ) &&
+        SearchAttrInfo* pAItem = &pList->GetObject(n);
+        if( !IsInvalidItem( pAItem->pItemPtr ) &&
             SfxItemState::SET == aOutSet.GetItemState(
-                pAItem->pItem->Which(), false, &pItem ) )
+                pAItem->pItemPtr->Which(), false, &pItem ) )
         {
-            delete pAItem->pItem;
-            pAItem->pItem = pItem->Clone();
-            aOutSet.ClearItem( pAItem->pItem->Which() );
+            delete pAItem->pItemPtr;
+            pAItem->pItemPtr = pItem->Clone();
+            aOutSet.ClearItem( pAItem->pItemPtr->Which() );
         }
     }
 
@@ -2135,15 +2135,15 @@ OUString& SvxSearchDialog::BuildAttrText_Impl( 
OUString& rStr,
     IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
     for ( sal_uInt16 i = 0; i < pList->Count(); ++i )
     {
-        const SearchAttrItem& rItem = pList->GetObject(i);
+        const SearchAttrInfo& rItem = pList->GetObject(i);
 
         if ( !rStr.isEmpty() )
             rStr += ", ";
 
-        if ( !IsInvalidItem( rItem.pItem ) )
+        if ( !IsInvalidItem( rItem.pItemPtr ) )
         {
             OUString aStr;
-            rPool.GetPresentation(*rItem.pItem, eMapUnit, aStr, aIntlWrapper);
+            rPool.GetPresentation(*rItem.pItemPtr, eMapUnit, aStr, 
aIntlWrapper);
             if (aStr.isEmpty())
             {
                 if (rStr.endsWith(", "))
diff --git a/svx/source/mnuctrls/clipboardctl.cxx 
b/svx/source/mnuctrls/clipboardctl.cxx
index 70b2620565bf..b5b55535f13a 100644
--- a/svx/source/mnuctrls/clipboardctl.cxx
+++ b/svx/source/mnuctrls/clipboardctl.cxx
@@ -22,6 +22,7 @@
 #include <comphelper/propertyvalue.hxx>
 #include <sfx2/tbxctrl.hxx>
 #include <svl/intitem.hxx>
+#include <svl/voiditem.hxx>
 #include <vcl/svapp.hxx>
 #include <vcl/toolbox.hxx>
 #include <vcl/weldutils.hxx>
diff --git a/svx/source/stbctrls/zoomctrl.cxx b/svx/source/stbctrls/zoomctrl.cxx
index 77bb47fce38f..9a86cc8ffb73 100644
--- a/svx/source/stbctrls/zoomctrl.cxx
+++ b/svx/source/stbctrls/zoomctrl.cxx
@@ -21,6 +21,7 @@
 
 #include <comphelper/propertyvalue.hxx>
 #include <i18nutil/unicode.hxx>
+#include <svl/voiditem.hxx>
 #include <vcl/commandevent.hxx>
 #include <vcl/event.hxx>
 #include <vcl/svapp.hxx>
diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx
index 9ed199d34586..0a4ce01cab2c 100644
--- a/svx/source/svdraw/svdattr.cxx
+++ b/svx/source/svdraw/svdattr.cxx
@@ -46,6 +46,7 @@
 #include <vcl/settings.hxx>
 
 #include <svl/grabbagitem.hxx>
+#include <svl/voiditem.hxx>
 
 #include <svx/strings.hrc>
 #include <svx/dialmgr.hxx>
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx 
b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index a5450d29b673..2e43441958f8 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -38,6 +38,7 @@
 #include <svl/srchitem.hxx>
 #include <svl/slstitm.hxx>
 #include <svl/stritem.hxx>
+#include <svl/voiditem.hxx>
 #include <sfx2/viewsh.hxx>
 #include <sfx2/bindings.hxx>
 #include <sfx2/dispatch.hxx>
diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx
index f2a4d974cfa1..3e286b31e80a 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -63,6 +63,7 @@
 #include <editeng/postitem.hxx>
 #include <editeng/rsiditem.hxx>
 #include <svl/grabbagitem.hxx>
+#include <svl/voiditem.hxx>
 #include <editeng/scriptspaceitem.hxx>
 #include <editeng/shaditem.hxx>
 #include <editeng/shdditem.hxx>
diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx 
b/sw/source/core/doc/DocumentContentOperationsManager.cxx
index 4ad364ea6afc..091da2714e02 100644
--- a/sw/source/core/doc/DocumentContentOperationsManager.cxx
+++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx
@@ -1293,9 +1293,10 @@ namespace //local functions originally from docfmt.cxx
             aSet.ClearItem( RES_TXTATR_META );
             aSet.ClearItem( RES_TXTATR_METAFIELD );
 
-            // After GetParaAttr aSet can contain INVALID_POOL_ITEM items, 
e.g. RES_TXTATR_CHARFMT
-            // and (a copy of) this SfxItemSet can be passed to 
MSWordExportBase::OutputItemSet
-            // which doesn't handle INVALID_POOL_ITEM items so clear 
InvalidItems here
+            // After GetParaAttr aSet can contain invalid/dontcare items (true 
== IsInvalidItem,
+            // DONTCARE == SfxItemState), e.g. RES_TXTATR_CHARFMT and (a copy 
of) this
+            // SfxItemSet can be passed to MSWordExportBase::OutputItemSet
+            // which doesn't handle invalid/dontcare items so clear them here
             aSet.ClearInvalidItems();
 
             xExtra.reset(new SwRedlineExtraData_FormatColl("", USHRT_MAX, 
&aSet));
diff --git a/sw/source/uibase/app/apphdl.cxx b/sw/source/uibase/app/apphdl.cxx
index 9d8dfadbdef6..fd687268eebd 100644
--- a/sw/source/uibase/app/apphdl.cxx
+++ b/sw/source/uibase/app/apphdl.cxx
@@ -30,6 +30,7 @@
 #include <svl/eitem.hxx>
 #include <svl/whiter.hxx>
 #include <svl/stritem.hxx>
+#include <svl/voiditem.hxx>
 #include <sfx2/request.hxx>
 #include <sfx2/fcontnr.hxx>
 #include <svl/ctloptions.hxx>
diff --git a/sw/source/uibase/app/applab.cxx b/sw/source/uibase/app/applab.cxx
index c39ec665da71..78436664c3cb 100644
--- a/sw/source/uibase/app/applab.cxx
+++ b/sw/source/uibase/app/applab.cxx
@@ -23,6 +23,7 @@
 #include <hintids.hxx>
 
 #include <comphelper/string.hxx>
+#include <svl/voiditem.hxx>
 #include <sfx2/dispatch.hxx>
 #include <sfx2/printer.hxx>
 #include <sfx2/request.hxx>
diff --git a/sw/source/uibase/lingu/olmenu.cxx 
b/sw/source/uibase/lingu/olmenu.cxx
index 80e32a4cdb30..acf06f2e41a7 100644
--- a/sw/source/uibase/lingu/olmenu.cxx
+++ b/sw/source/uibase/lingu/olmenu.cxx
@@ -54,6 +54,7 @@
 #include <svl/itemset.hxx>
 #include <svl/languageoptions.hxx>
 #include <svl/stritem.hxx>
+#include <svl/voiditem.hxx>
 #include <svtools/langtab.hxx>
 #include <unotools/lingucfg.hxx>
 #include <unotools/linguprops.hxx>
diff --git a/sw/source/uibase/ribbar/workctrl.cxx 
b/sw/source/uibase/ribbar/workctrl.cxx
index eed488a72c46..03c883dc0155 100644
--- a/sw/source/uibase/ribbar/workctrl.cxx
+++ b/sw/source/uibase/ribbar/workctrl.cxx
@@ -36,6 +36,7 @@
 #include <wrtsh.hxx>
 #include <cppuhelper/queryinterface.hxx>
 #include <cppuhelper/supportsservice.hxx>
+#include <svl/voiditem.hxx>
 #include <vcl/event.hxx>
 #include <vcl/menu.hxx>
 #include <vcl/settings.hxx>
diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx
index 6fed89a5fdd7..4b7fc313bbb1 100644
--- a/vcl/source/app/svapp.cxx
+++ b/vcl/source/app/svapp.cxx
@@ -74,6 +74,10 @@
 #include <comphelper/solarmutex.hxx>
 #include <osl/process.h>
 
+#ifdef DBG_UTIL
+#include <svl/poolitem.hxx>
+#endif
+
 #include <cassert>
 #include <limits>
 #include <string_view>
@@ -174,6 +178,21 @@ Application::~Application()
 {
     ImplDeInitSVData();
     ImplGetSVData()->mpApp = nullptr;
+#ifdef DBG_UTIL
+    // Due to
+    //   svx/source/dialog/framelinkarray.cxx
+    //   class Cell final : public SfxPoolItem
+    //   const Cell OBJ_CELL_NONE;
+    // being a static held SfxPoolItem which is not yet de-initialized here
+    // number often is (1), even higher with other modules loaded (like 5).
+    // These get de-allocated reliaby in module-deinitializations, so this
+    // is no memory loss. These counters are more to be able to have an eye
+    // on amounts of SfxPoolItems used during office usage and to be able to
+    // detect if an error in future changes may lead to memory losses - these
+    // would show in dramaitically higher numbers then imediately
+    SAL_WARN("vcl", "ITEM: " << getAllocatedSfxPoolItemCount() << " 
SfxPoolItems still allocated at shutdown");
+    SAL_WARN("vcl", "ITEM: " << getUsedSfxPoolItemCount() << " SfxPoolItems 
were incarnated during office usage");
+#endif
 }
 
 int Application::Main()

Reply via email to