basegfx/source/polygon/b2dpolygon.cxx      |   52 +++++++++++------------
 basegfx/source/polygon/b2dpolypolygon.cxx  |   16 +++----
 basegfx/source/polygon/b3dpolygon.cxx      |   34 +++++++--------
 basegfx/source/polygon/b3dpolypolygon.cxx  |   10 ++--
 compilerplugins/clang/cow_wrapper.cxx      |   65 +++++++++++++++++++++--------
 compilerplugins/clang/test/cow_wrapper.cxx |   11 ++++
 svx/source/xoutdev/_xpoly.cxx              |   10 ++--
 vcl/source/font/font.cxx                   |    6 +-
 8 files changed, 124 insertions(+), 80 deletions(-)

New commits:
commit 5de20e45e48f7654d288f26f768fabddad133bfd
Author:     Noel Grandin <noel.gran...@collabora.co.uk>
AuthorDate: Tue Dec 7 14:37:56 2021 +0200
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Tue Dec 7 17:46:23 2021 +0100

    improve loplugin:cow_wrapper
    
    to find my previous attempt at this, which only obscured the problem
    
    <noelgrandin> I'm such an idiot
    <noelgrandin> I changed a whole bunch of code to avoid calling const
    methods on a non-const object
    <noelgrandin> from p->foo() to std::as_const(*p).foo()
    <noelgrandin> can you spot the mistake?
    <bubli> Is this a job interview question? :D
    <vmiklos> noelgrandin: you did the opposite, now you always call const
    member functions, while you wanted to always call non-const member
    functions?
    <noelgrandin> more like a "why didn't the smart people on this channel
    tell me I was an idiot" :-)
    <noelgrandin> in this case, we have o3tl::cow_wrapper, which overrides
    operator* and operator->
    <vmiklos> ah, and by the time you would add/remove the const,
    cow_wrapper already did the expensive task of copying based on
    const/non-const
    <noelgrandin> exactly
    <thorsten> heh
    
    Change-Id: I5366e6a87c414b862668b61e6adfbccfdd9d3b04
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/126473
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/basegfx/source/polygon/b2dpolygon.cxx 
b/basegfx/source/polygon/b2dpolygon.cxx
index a1d50321e8e9..4d2b681911e2 100644
--- a/basegfx/source/polygon/b2dpolygon.cxx
+++ b/basegfx/source/polygon/b2dpolygon.cxx
@@ -1177,9 +1177,9 @@ namespace basegfx
 
     void B2DPolygon::setB2DPoint(sal_uInt32 nIndex, const B2DPoint& rValue)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B2DPolygon 
access outside range (!)");
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon 
access outside range (!)");
 
-        if(std::as_const(*mpPolygon).getPoint(nIndex) != rValue)
+        if(std::as_const(mpPolygon)->getPoint(nIndex) != rValue)
         {
             mpPolygon->setPoint(nIndex, rValue);
         }
@@ -1192,7 +1192,7 @@ namespace basegfx
 
     void B2DPolygon::insert(sal_uInt32 nIndex, const B2DPoint& rPoint, 
sal_uInt32 nCount)
     {
-        OSL_ENSURE(nIndex <= std::as_const(*mpPolygon).count(), "B2DPolygon 
Insert outside range (!)");
+        OSL_ENSURE(nIndex <= std::as_const(mpPolygon)->count(), "B2DPolygon 
Insert outside range (!)");
 
         if(nCount)
         {
@@ -1204,7 +1204,7 @@ namespace basegfx
     {
         if(nCount)
         {
-            mpPolygon->insert(std::as_const(*mpPolygon).count(), rPoint, 
nCount);
+            mpPolygon->insert(std::as_const(mpPolygon)->count(), rPoint, 
nCount);
         }
     }
 
@@ -1243,10 +1243,10 @@ namespace basegfx
 
     void B2DPolygon::setPrevControlPoint(sal_uInt32 nIndex, const B2DPoint& 
rValue)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B2DPolygon 
access outside range (!)");
-        const basegfx::B2DVector aNewVector(rValue - 
std::as_const(*mpPolygon).getPoint(nIndex));
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon 
access outside range (!)");
+        const basegfx::B2DVector aNewVector(rValue - 
std::as_const(mpPolygon)->getPoint(nIndex));
 
-        if(std::as_const(*mpPolygon).getPrevControlVector(nIndex) != 
aNewVector)
+        if(std::as_const(mpPolygon)->getPrevControlVector(nIndex) != 
aNewVector)
         {
             mpPolygon->setPrevControlVector(nIndex, aNewVector);
         }
@@ -1254,10 +1254,10 @@ namespace basegfx
 
     void B2DPolygon::setNextControlPoint(sal_uInt32 nIndex, const B2DPoint& 
rValue)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B2DPolygon 
access outside range (!)");
-        const basegfx::B2DVector aNewVector(rValue - 
std::as_const(*mpPolygon).getPoint(nIndex));
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon 
access outside range (!)");
+        const basegfx::B2DVector aNewVector(rValue - 
std::as_const(mpPolygon)->getPoint(nIndex));
 
-        if(std::as_const(*mpPolygon).getNextControlVector(nIndex) != 
aNewVector)
+        if(std::as_const(mpPolygon)->getNextControlVector(nIndex) != 
aNewVector)
         {
             mpPolygon->setNextControlVector(nIndex, aNewVector);
         }
@@ -1265,12 +1265,12 @@ namespace basegfx
 
     void B2DPolygon::setControlPoints(sal_uInt32 nIndex, const 
basegfx::B2DPoint& rPrev, const basegfx::B2DPoint& rNext)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B2DPolygon 
access outside range (!)");
-        const B2DPoint aPoint(std::as_const(*mpPolygon).getPoint(nIndex));
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon 
access outside range (!)");
+        const B2DPoint aPoint(std::as_const(mpPolygon)->getPoint(nIndex));
         const basegfx::B2DVector aNewPrev(rPrev - aPoint);
         const basegfx::B2DVector aNewNext(rNext - aPoint);
 
-        if(std::as_const(*mpPolygon).getPrevControlVector(nIndex) != aNewPrev 
|| std::as_const(*mpPolygon).getNextControlVector(nIndex) != aNewNext)
+        if(std::as_const(mpPolygon)->getPrevControlVector(nIndex) != aNewPrev 
|| std::as_const(mpPolygon)->getNextControlVector(nIndex) != aNewNext)
         {
             mpPolygon->setControlVectors(nIndex, aNewPrev, aNewNext);
         }
@@ -1278,9 +1278,9 @@ namespace basegfx
 
     void B2DPolygon::resetPrevControlPoint(sal_uInt32 nIndex)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B2DPolygon 
access outside range (!)");
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon 
access outside range (!)");
 
-        if(std::as_const(*mpPolygon).areControlPointsUsed() && 
!std::as_const(*mpPolygon).getPrevControlVector(nIndex).equalZero())
+        if(std::as_const(mpPolygon)->areControlPointsUsed() && 
!std::as_const(mpPolygon)->getPrevControlVector(nIndex).equalZero())
         {
             mpPolygon->setPrevControlVector(nIndex, 
B2DVector::getEmptyVector());
         }
@@ -1288,9 +1288,9 @@ namespace basegfx
 
     void B2DPolygon::resetNextControlPoint(sal_uInt32 nIndex)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B2DPolygon 
access outside range (!)");
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B2DPolygon 
access outside range (!)");
 
-        if(std::as_const(*mpPolygon).areControlPointsUsed() && 
!std::as_const(*mpPolygon).getNextControlVector(nIndex).equalZero())
+        if(std::as_const(mpPolygon)->areControlPointsUsed() && 
!std::as_const(mpPolygon)->getNextControlVector(nIndex).equalZero())
         {
             mpPolygon->setNextControlVector(nIndex, 
B2DVector::getEmptyVector());
         }
@@ -1298,7 +1298,7 @@ namespace basegfx
 
     void B2DPolygon::resetControlPoints()
     {
-        if(std::as_const(*mpPolygon).areControlPointsUsed())
+        if(std::as_const(mpPolygon)->areControlPointsUsed())
         {
             mpPolygon->resetControlVectors();
         }
@@ -1309,12 +1309,12 @@ namespace basegfx
         const B2DPoint& rPrevControlPoint,
         const B2DPoint& rPoint)
     {
-        const B2DVector aNewNextVector(std::as_const(*mpPolygon).count() ? 
B2DVector(rNextControlPoint - 
std::as_const(*mpPolygon).getPoint(std::as_const(*mpPolygon).count() - 1)) : 
B2DVector::getEmptyVector());
+        const B2DVector aNewNextVector(std::as_const(mpPolygon)->count() ? 
B2DVector(rNextControlPoint - 
std::as_const(mpPolygon)->getPoint(std::as_const(mpPolygon)->count() - 1)) : 
B2DVector::getEmptyVector());
         const B2DVector aNewPrevVector(rPrevControlPoint - rPoint);
 
         if(aNewNextVector.equalZero() && aNewPrevVector.equalZero())
         {
-            mpPolygon->insert(std::as_const(*mpPolygon).count(), rPoint, 1);
+            mpPolygon->insert(std::as_const(mpPolygon)->count(), rPoint, 1);
         }
         else
         {
@@ -1324,7 +1324,7 @@ namespace basegfx
 
     void B2DPolygon::appendQuadraticBezierSegment(const B2DPoint& 
rControlPoint, const B2DPoint& rPoint)
     {
-        if (std::as_const(*mpPolygon).count() == 0)
+        if (std::as_const(mpPolygon)->count() == 0)
         {
             mpPolygon->append(rPoint);
             const double nX((rControlPoint.getX() * 2.0 + rPoint.getX()) / 
3.0);
@@ -1333,7 +1333,7 @@ namespace basegfx
         }
         else
         {
-            const B2DPoint 
aPreviousPoint(std::as_const(*mpPolygon).getPoint(std::as_const(*mpPolygon).count()
 - 1));
+            const B2DPoint 
aPreviousPoint(std::as_const(mpPolygon)->getPoint(std::as_const(mpPolygon)->count()
 - 1));
 
             const double nX1((rControlPoint.getX() * 2.0 + 
aPreviousPoint.getX()) / 3.0);
             const double nY1((rControlPoint.getY() * 2.0 + 
aPreviousPoint.getY()) / 3.0);
@@ -1436,19 +1436,19 @@ namespace basegfx
 
         if(nIndex == 0 && nCount == rPoly.count())
         {
-            mpPolygon->insert(std::as_const(*mpPolygon).count(), 
*rPoly.mpPolygon);
+            mpPolygon->insert(std::as_const(mpPolygon)->count(), 
*rPoly.mpPolygon);
         }
         else
         {
             OSL_ENSURE(nIndex + nCount <= rPoly.mpPolygon->count(), 
"B2DPolygon Append outside range (!)");
             ImplB2DPolygon aTempPoly(*rPoly.mpPolygon, nIndex, nCount);
-            mpPolygon->insert(std::as_const(*mpPolygon).count(), aTempPoly);
+            mpPolygon->insert(std::as_const(mpPolygon)->count(), aTempPoly);
         }
     }
 
     void B2DPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
     {
-        OSL_ENSURE(nIndex + nCount <= std::as_const(*mpPolygon).count(), 
"B2DPolygon Remove outside range (!)");
+        OSL_ENSURE(nIndex + nCount <= std::as_const(mpPolygon)->count(), 
"B2DPolygon Remove outside range (!)");
 
         if(nCount)
         {
@@ -1498,7 +1498,7 @@ namespace basegfx
 
     void B2DPolygon::transform(const B2DHomMatrix& rMatrix)
     {
-        if(std::as_const(*mpPolygon).count() && !rMatrix.isIdentity())
+        if(std::as_const(mpPolygon)->count() && !rMatrix.isIdentity())
         {
             mpPolygon->transform(rMatrix);
         }
diff --git a/basegfx/source/polygon/b2dpolypolygon.cxx 
b/basegfx/source/polygon/b2dpolypolygon.cxx
index 34ff30877ea8..13724164ff2f 100644
--- a/basegfx/source/polygon/b2dpolypolygon.cxx
+++ b/basegfx/source/polygon/b2dpolypolygon.cxx
@@ -249,7 +249,7 @@ namespace basegfx
 
     void B2DPolyPolygon::setB2DPolygon(sal_uInt32 nIndex, const B2DPolygon& 
rPolygon)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolyPolygon).count(), 
"B2DPolyPolygon access outside range (!)");
+        OSL_ENSURE(nIndex < std::as_const(mpPolyPolygon)->count(), 
"B2DPolyPolygon access outside range (!)");
 
         if(getB2DPolygon(nIndex) != rPolygon)
             mpPolyPolygon->setB2DPolygon(nIndex, rPolygon);
@@ -272,7 +272,7 @@ namespace basegfx
 
     void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolygon& rPolygon, 
sal_uInt32 nCount)
     {
-        OSL_ENSURE(nIndex <= std::as_const(*mpPolyPolygon).count(), 
"B2DPolyPolygon Insert outside range (!)");
+        OSL_ENSURE(nIndex <= std::as_const(mpPolyPolygon)->count(), 
"B2DPolyPolygon Insert outside range (!)");
 
         if(nCount)
             mpPolyPolygon->insert(nIndex, rPolygon, nCount);
@@ -281,7 +281,7 @@ namespace basegfx
     void B2DPolyPolygon::append(const B2DPolygon& rPolygon, sal_uInt32 nCount)
     {
         if(nCount)
-            mpPolyPolygon->insert(std::as_const(*mpPolyPolygon).count(), 
rPolygon, nCount);
+            mpPolyPolygon->insert(std::as_const(mpPolyPolygon)->count(), 
rPolygon, nCount);
     }
 
     B2DPolyPolygon B2DPolyPolygon::getDefaultAdaptiveSubdivision() const
@@ -310,7 +310,7 @@ namespace basegfx
 
     void B2DPolyPolygon::insert(sal_uInt32 nIndex, const B2DPolyPolygon& 
rPolyPolygon)
     {
-        OSL_ENSURE(nIndex <= std::as_const(*mpPolyPolygon).count(), 
"B2DPolyPolygon Insert outside range (!)");
+        OSL_ENSURE(nIndex <= std::as_const(mpPolyPolygon)->count(), 
"B2DPolyPolygon Insert outside range (!)");
 
         if(rPolyPolygon.count())
             mpPolyPolygon->insert(nIndex, rPolyPolygon);
@@ -319,12 +319,12 @@ namespace basegfx
     void B2DPolyPolygon::append(const B2DPolyPolygon& rPolyPolygon)
     {
         if(rPolyPolygon.count())
-            mpPolyPolygon->insert(std::as_const(*mpPolyPolygon).count(), 
rPolyPolygon);
+            mpPolyPolygon->insert(std::as_const(mpPolyPolygon)->count(), 
rPolyPolygon);
     }
 
     void B2DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
     {
-        OSL_ENSURE(nIndex + nCount <= std::as_const(*mpPolyPolygon).count(), 
"B2DPolyPolygon Remove outside range (!)");
+        OSL_ENSURE(nIndex + nCount <= std::as_const(mpPolyPolygon)->count(), 
"B2DPolyPolygon Remove outside range (!)");
 
         if(nCount)
             mpPolyPolygon->remove(nIndex, nCount);
@@ -360,7 +360,7 @@ namespace basegfx
 
     void B2DPolyPolygon::flip()
     {
-        if(std::as_const(*mpPolyPolygon).count())
+        if(std::as_const(mpPolyPolygon)->count())
         {
             mpPolyPolygon->flip();
         }
@@ -389,7 +389,7 @@ namespace basegfx
 
     void B2DPolyPolygon::transform(const B2DHomMatrix& rMatrix)
     {
-        if(std::as_const(*mpPolyPolygon).count() && !rMatrix.isIdentity())
+        if(std::as_const(mpPolyPolygon)->count() && !rMatrix.isIdentity())
         {
             mpPolyPolygon->transform(rMatrix);
         }
diff --git a/basegfx/source/polygon/b3dpolygon.cxx 
b/basegfx/source/polygon/b3dpolygon.cxx
index dac943c79049..a14b9f3887b8 100644
--- a/basegfx/source/polygon/b3dpolygon.cxx
+++ b/basegfx/source/polygon/b3dpolygon.cxx
@@ -1431,7 +1431,7 @@ namespace basegfx
 
     void B3DPolygon::setB3DPoint(sal_uInt32 nIndex, const basegfx::B3DPoint& 
rValue)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B3DPolygon 
access outside range (!)");
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B3DPolygon 
access outside range (!)");
 
         if(getB3DPoint(nIndex) != rValue)
             mpPolygon->setPoint(nIndex, rValue);
@@ -1446,9 +1446,9 @@ namespace basegfx
 
     void B3DPolygon::setBColor(sal_uInt32 nIndex, const BColor& rValue)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B3DPolygon 
access outside range (!)");
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B3DPolygon 
access outside range (!)");
 
-        if(std::as_const(*mpPolygon).getBColor(nIndex) != rValue)
+        if(std::as_const(mpPolygon)->getBColor(nIndex) != rValue)
             mpPolygon->setBColor(nIndex, rValue);
     }
 
@@ -1459,7 +1459,7 @@ namespace basegfx
 
     void B3DPolygon::clearBColors()
     {
-        if(std::as_const(*mpPolygon).areBColorsUsed())
+        if(std::as_const(mpPolygon)->areBColorsUsed())
             mpPolygon->clearBColors();
     }
 
@@ -1477,15 +1477,15 @@ namespace basegfx
 
     void B3DPolygon::setNormal(sal_uInt32 nIndex, const B3DVector& rValue)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B3DPolygon 
access outside range (!)");
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B3DPolygon 
access outside range (!)");
 
-        if(std::as_const(*mpPolygon).getNormal(nIndex) != rValue)
+        if(std::as_const(mpPolygon)->getNormal(nIndex) != rValue)
             mpPolygon->setNormal(nIndex, rValue);
     }
 
     void B3DPolygon::transformNormals(const B3DHomMatrix& rMatrix)
     {
-        if(std::as_const(*mpPolygon).areNormalsUsed() && !rMatrix.isIdentity())
+        if(std::as_const(mpPolygon)->areNormalsUsed() && !rMatrix.isIdentity())
             mpPolygon->transformNormals(rMatrix);
     }
 
@@ -1496,7 +1496,7 @@ namespace basegfx
 
     void B3DPolygon::clearNormals()
     {
-        if(std::as_const(*mpPolygon).areNormalsUsed())
+        if(std::as_const(mpPolygon)->areNormalsUsed())
             mpPolygon->clearNormals();
     }
 
@@ -1509,15 +1509,15 @@ namespace basegfx
 
     void B3DPolygon::setTextureCoordinate(sal_uInt32 nIndex, const B2DPoint& 
rValue)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B3DPolygon 
access outside range (!)");
+        OSL_ENSURE(nIndex < std::as_const(mpPolygon)->count(), "B3DPolygon 
access outside range (!)");
 
-        if(std::as_const(*mpPolygon).getTextureCoordinate(nIndex) != rValue)
+        if(std::as_const(mpPolygon)->getTextureCoordinate(nIndex) != rValue)
             mpPolygon->setTextureCoordinate(nIndex, rValue);
     }
 
     void B3DPolygon::transformTextureCoordinates(const B2DHomMatrix& rMatrix)
     {
-        if(std::as_const(*mpPolygon).areTextureCoordinatesUsed() && 
!rMatrix.isIdentity())
+        if(std::as_const(mpPolygon)->areTextureCoordinatesUsed() && 
!rMatrix.isIdentity())
             mpPolygon->transformTextureCoordinates(rMatrix);
     }
 
@@ -1528,14 +1528,14 @@ namespace basegfx
 
     void B3DPolygon::clearTextureCoordinates()
     {
-        if(std::as_const(*mpPolygon).areTextureCoordinatesUsed())
+        if(std::as_const(mpPolygon)->areTextureCoordinatesUsed())
             mpPolygon->clearTextureCoordinates();
     }
 
     void B3DPolygon::append(const basegfx::B3DPoint& rPoint, sal_uInt32 nCount)
     {
         if(nCount)
-            mpPolygon->insert(std::as_const(*mpPolygon).count(), rPoint, 
nCount);
+            mpPolygon->insert(std::as_const(mpPolygon)->count(), rPoint, 
nCount);
     }
 
     void B3DPolygon::append(const B3DPolygon& rPoly, sal_uInt32 nIndex, 
sal_uInt32 nCount)
@@ -1550,19 +1550,19 @@ namespace basegfx
 
         if(nIndex == 0 && nCount == rPoly.count())
         {
-            mpPolygon->insert(std::as_const(*mpPolygon).count(), 
*rPoly.mpPolygon);
+            mpPolygon->insert(std::as_const(mpPolygon)->count(), 
*rPoly.mpPolygon);
         }
         else
         {
             OSL_ENSURE(nIndex + nCount <= rPoly.mpPolygon->count(), 
"B3DPolygon Append outside range (!)");
             ImplB3DPolygon aTempPoly(*rPoly.mpPolygon, nIndex, nCount);
-            mpPolygon->insert(std::as_const(*mpPolygon).count(), aTempPoly);
+            mpPolygon->insert(std::as_const(mpPolygon)->count(), aTempPoly);
         }
     }
 
     void B3DPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
     {
-        OSL_ENSURE(nIndex + nCount <= std::as_const(*mpPolygon).count(), 
"B3DPolygon Remove outside range (!)");
+        OSL_ENSURE(nIndex + nCount <= std::as_const(mpPolygon)->count(), 
"B3DPolygon Remove outside range (!)");
 
         if(nCount)
             mpPolygon->remove(nIndex, nCount);
@@ -1606,7 +1606,7 @@ namespace basegfx
 
     void B3DPolygon::transform(const basegfx::B3DHomMatrix& rMatrix)
     {
-        if(std::as_const(*mpPolygon).count() && !rMatrix.isIdentity())
+        if(std::as_const(mpPolygon)->count() && !rMatrix.isIdentity())
         {
             mpPolygon->transform(rMatrix);
         }
diff --git a/basegfx/source/polygon/b3dpolypolygon.cxx 
b/basegfx/source/polygon/b3dpolypolygon.cxx
index 4104d2fc29fe..e7334af42874 100644
--- a/basegfx/source/polygon/b3dpolypolygon.cxx
+++ b/basegfx/source/polygon/b3dpolypolygon.cxx
@@ -241,7 +241,7 @@ namespace basegfx
 
     void B3DPolyPolygon::setB3DPolygon(sal_uInt32 nIndex, const B3DPolygon& 
rPolygon)
     {
-        OSL_ENSURE(nIndex < std::as_const(*mpPolyPolygon).count(), 
"B3DPolyPolygon access outside range (!)");
+        OSL_ENSURE(nIndex < std::as_const(mpPolyPolygon)->count(), 
"B3DPolyPolygon access outside range (!)");
 
         if(getB3DPolygon(nIndex) != rPolygon)
             mpPolyPolygon->setB3DPolygon(nIndex, rPolygon);
@@ -319,18 +319,18 @@ namespace basegfx
     void B3DPolyPolygon::append(const B3DPolygon& rPolygon, sal_uInt32 nCount)
     {
         if(nCount)
-            mpPolyPolygon->insert(std::as_const(*mpPolyPolygon).count(), 
rPolygon, nCount);
+            mpPolyPolygon->insert(std::as_const(mpPolyPolygon)->count(), 
rPolygon, nCount);
     }
 
     void B3DPolyPolygon::append(const B3DPolyPolygon& rPolyPolygon)
     {
         if(rPolyPolygon.count())
-            mpPolyPolygon->insert(std::as_const(*mpPolyPolygon).count(), 
rPolyPolygon);
+            mpPolyPolygon->insert(std::as_const(mpPolyPolygon)->count(), 
rPolyPolygon);
     }
 
     void B3DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount)
     {
-        OSL_ENSURE(nIndex + nCount <= std::as_const(*mpPolyPolygon).count(), 
"B3DPolyPolygon Remove outside range (!)");
+        OSL_ENSURE(nIndex + nCount <= std::as_const(mpPolyPolygon)->count(), 
"B3DPolyPolygon Remove outside range (!)");
 
         if(nCount)
             mpPolyPolygon->remove(nIndex, nCount);
@@ -369,7 +369,7 @@ namespace basegfx
 
     void B3DPolyPolygon::transform(const B3DHomMatrix& rMatrix)
     {
-        if(std::as_const(*mpPolyPolygon).count() && !rMatrix.isIdentity())
+        if(std::as_const(mpPolyPolygon)->count() && !rMatrix.isIdentity())
         {
             mpPolyPolygon->transform(rMatrix);
         }
diff --git a/compilerplugins/clang/cow_wrapper.cxx 
b/compilerplugins/clang/cow_wrapper.cxx
index 4c04674f65c1..d5d1b47b3a43 100644
--- a/compilerplugins/clang/cow_wrapper.cxx
+++ b/compilerplugins/clang/cow_wrapper.cxx
@@ -53,22 +53,55 @@ bool Cow_Wrapper::VisitCXXMemberCallExpr(const 
CXXMemberCallExpr* memberCallExpr
     if (!methodDecl || !methodDecl->isConst())
         return true;
 
-    auto operatorCallExpr = dyn_cast<CXXOperatorCallExpr>(
-        compat::IgnoreImplicit(memberCallExpr->getImplicitObjectArgument()));
-    if (!operatorCallExpr)
-        return true;
-    if (operatorCallExpr->getOperator() != OO_Arrow)
-        return true;
-    auto arrowMethodDecl = 
dyn_cast_or_null<CXXMethodDecl>(operatorCallExpr->getDirectCallee());
-    if (!arrowMethodDecl)
-        return true;
-    if (arrowMethodDecl->isConst())
-        return true;
-    auto dc = loplugin::DeclCheck(arrowMethodDecl->getParent())
-                  .Class("cow_wrapper")
-                  .Namespace("o3tl")
-                  .GlobalNamespace();
-    if (!dc)
+    auto expr = 
compat::IgnoreImplicit(memberCallExpr->getImplicitObjectArgument())->IgnoreParens();
+    auto operatorCallExpr = dyn_cast<CXXOperatorCallExpr>(expr);
+
+    if (operatorCallExpr && operatorCallExpr->getOperator() == OO_Arrow)
+    {
+        auto arrowMethodDecl = 
dyn_cast_or_null<CXXMethodDecl>(operatorCallExpr->getDirectCallee());
+        if (!arrowMethodDecl)
+            return true;
+        if (arrowMethodDecl->isConst())
+            return true;
+        auto dc = loplugin::DeclCheck(arrowMethodDecl->getParent())
+                      .Class("cow_wrapper")
+                      .Namespace("o3tl")
+                      .GlobalNamespace();
+        if (!dc)
+            return true;
+    }
+    else if (operatorCallExpr)
+    {
+        auto methodDecl2 = 
dyn_cast_or_null<CXXMethodDecl>(operatorCallExpr->getDirectCallee());
+        if (!methodDecl2)
+            return true;
+        auto dc = loplugin::DeclCheck(methodDecl2->getParent())
+                      .Class("cow_wrapper")
+                      .Namespace("o3tl")
+                      .GlobalNamespace();
+        if (!dc)
+            return true;
+    }
+    else if (auto callExpr = dyn_cast<CallExpr>(expr))
+    {
+        if (!isa<ImplicitCastExpr>(callExpr->getCallee())) // std::as_const 
shows up as this
+            return true;
+        if (callExpr->getNumArgs() < 1)
+            return true;
+        auto arg0 = dyn_cast<CXXOperatorCallExpr>(callExpr->getArg(0));
+        if (!arg0)
+            return true;
+        auto starMethodDecl = 
dyn_cast_or_null<CXXMethodDecl>(arg0->getDirectCallee());
+        if (!starMethodDecl)
+            return true;
+        auto dc = loplugin::DeclCheck(starMethodDecl->getParent())
+                      .Class("cow_wrapper")
+                      .Namespace("o3tl")
+                      .GlobalNamespace();
+        if (!dc)
+            return true;
+    }
+    else
         return true;
 
     report(DiagnosticsEngine::Warning,
diff --git a/compilerplugins/clang/test/cow_wrapper.cxx 
b/compilerplugins/clang/test/cow_wrapper.cxx
index 705a4052ef66..5c95f87f04d9 100644
--- a/compilerplugins/clang/test/cow_wrapper.cxx
+++ b/compilerplugins/clang/test/cow_wrapper.cxx
@@ -9,6 +9,7 @@
 
 #include "config_clang.h"
 #include "o3tl/cow_wrapper.hxx"
+#include <utility>
 
 struct ImplBitmapPalette
 {
@@ -27,6 +28,16 @@ struct BitmapPalette
         // no error expected
         mpImpl->foo();
     }
+    void foo3()
+    {
+        // expected-error@+1 {{calling const method on o3tl::cow_wrapper impl 
class via non-const pointer, rather use std::as_const to prevent triggering an 
unnecessary copy [loplugin:cow_wrapper]}}
+        (*mpImpl).foo();
+    }
+    void foo4()
+    {
+        // expected-error@+1 {{calling const method on o3tl::cow_wrapper impl 
class via non-const pointer, rather use std::as_const to prevent triggering an 
unnecessary copy [loplugin:cow_wrapper]}}
+        std::as_const(*mpImpl).foo();
+    }
     o3tl::cow_wrapper<ImplBitmapPalette> mpImpl;
 };
 
diff --git a/svx/source/xoutdev/_xpoly.cxx b/svx/source/xoutdev/_xpoly.cxx
index c4d74b996735..5cdbdacc93a3 100644
--- a/svx/source/xoutdev/_xpoly.cxx
+++ b/svx/source/xoutdev/_xpoly.cxx
@@ -322,7 +322,7 @@ XPolygon::~XPolygon() = default;
 
 void XPolygon::SetPointCount( sal_uInt16 nPoints )
 {
-    std::as_const(*pImpXPolygon).CheckPointDelete();
+    std::as_const(pImpXPolygon)->CheckPointDelete();
 
     if( pImpXPolygon->nSize < nPoints )
         pImpXPolygon->Resize( nPoints );
@@ -425,7 +425,7 @@ const Point& XPolygon::operator[]( sal_uInt16 nPos ) const
 
 Point& XPolygon::operator[]( sal_uInt16 nPos )
 {
-    std::as_const(*pImpXPolygon).CheckPointDelete();
+    std::as_const(pImpXPolygon)->CheckPointDelete();
 
     if( nPos >= pImpXPolygon->nSize )
     {
@@ -458,7 +458,7 @@ PolyFlags XPolygon::GetFlags( sal_uInt16 nPos ) const
 /// set the flags for the point at the given position
 void XPolygon::SetFlags( sal_uInt16 nPos, PolyFlags eFlags )
 {
-    std::as_const(*pImpXPolygon).CheckPointDelete();
+    std::as_const(pImpXPolygon)->CheckPointDelete();
     pImpXPolygon->pFlagAry[nPos] = eFlags;
 }
 
@@ -741,7 +741,7 @@ void XPolygon::PointsToBezier(sal_uInt16 nFirst)
 /// scale in X- and/or Y-direction
 void XPolygon::Scale(double fSx, double fSy)
 {
-    std::as_const(*pImpXPolygon).CheckPointDelete();
+    std::as_const(pImpXPolygon)->CheckPointDelete();
 
     sal_uInt16 nPntCnt = pImpXPolygon->nPoints;
 
@@ -766,7 +766,7 @@ void XPolygon::Scale(double fSx, double fSy)
 void XPolygon::Distort(const tools::Rectangle& rRefRect,
                        const XPolygon& rDistortedRect)
 {
-    std::as_const(*pImpXPolygon).CheckPointDelete();
+    std::as_const(pImpXPolygon)->CheckPointDelete();
 
     tools::Long    Xr, Wr;
     tools::Long    Yr, Hr;
diff --git a/vcl/source/font/font.cxx b/vcl/source/font/font.cxx
index ef35c744ee0a..789273aaf40b 100644
--- a/vcl/source/font/font.cxx
+++ b/vcl/source/font/font.cxx
@@ -184,7 +184,7 @@ void Font::SetSymbolFlag( bool bSymbol )
         }
         else
         {
-            if ( std::as_const(*mpImplFont).GetCharSet() == 
RTL_TEXTENCODING_SYMBOL )
+            if ( std::as_const(mpImplFont)->GetCharSet() == 
RTL_TEXTENCODING_SYMBOL )
                 mpImplFont->SetCharSet( RTL_TEXTENCODING_DONTKNOW );
         }
     }
@@ -851,9 +851,9 @@ const OUString& Font::GetFamilyName() const { return 
mpImplFont->GetFamilyName()
 const OUString& Font::GetStyleName() const { return mpImplFont->maStyleName; }
 
 const Size& Font::GetFontSize() const { return mpImplFont->GetFontSize(); }
-void Font::SetFontHeight( tools::Long nHeight ) { SetFontSize( Size( 
std::as_const(*mpImplFont).GetFontSize().Width(), nHeight ) ); }
+void Font::SetFontHeight( tools::Long nHeight ) { SetFontSize( Size( 
std::as_const(mpImplFont)->GetFontSize().Width(), nHeight ) ); }
 tools::Long Font::GetFontHeight() const { return 
mpImplFont->GetFontSize().Height(); }
-void Font::SetAverageFontWidth( tools::Long nWidth ) { SetFontSize( Size( 
nWidth, std::as_const(*mpImplFont).GetFontSize().Height() ) ); }
+void Font::SetAverageFontWidth( tools::Long nWidth ) { SetFontSize( Size( 
nWidth, std::as_const(mpImplFont)->GetFontSize().Height() ) ); }
 tools::Long Font::GetAverageFontWidth() const { return 
mpImplFont->GetFontSize().Width(); }
 
 rtl_TextEncoding Font::GetCharSet() const { return mpImplFont->GetCharSet(); }

Reply via email to