diff options
-rw-r--r-- | basegfx/source/polygon/b2dpolygon.cxx | 52 | ||||
-rw-r--r-- | basegfx/source/polygon/b2dpolypolygon.cxx | 16 | ||||
-rw-r--r-- | basegfx/source/polygon/b3dpolygon.cxx | 34 | ||||
-rw-r--r-- | basegfx/source/polygon/b3dpolypolygon.cxx | 10 | ||||
-rw-r--r-- | compilerplugins/clang/cow_wrapper.cxx | 88 | ||||
-rw-r--r-- | compilerplugins/clang/test/cow_wrapper.cxx | 33 | ||||
-rw-r--r-- | solenv/CompilerTest_compilerplugins_clang.mk | 1 | ||||
-rw-r--r-- | svx/source/xoutdev/_xpoly.cxx | 10 | ||||
-rw-r--r-- | vcl/source/font/font.cxx | 6 |
9 files changed, 186 insertions, 64 deletions
diff --git a/basegfx/source/polygon/b2dpolygon.cxx b/basegfx/source/polygon/b2dpolygon.cxx index e8f6d947c7d2..7276208cd326 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 < mpPolygon->count(), "B2DPolygon access outside range (!)"); + OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B2DPolygon access outside range (!)"); - if(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 <= 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(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 < mpPolygon->count(), "B2DPolygon access outside range (!)"); - const basegfx::B2DVector aNewVector(rValue - 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(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 < mpPolygon->count(), "B2DPolygon access outside range (!)"); - const basegfx::B2DVector aNewVector(rValue - 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(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 < mpPolygon->count(), "B2DPolygon access outside range (!)"); - const B2DPoint aPoint(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(mpPolygon->getPrevControlVector(nIndex) != aNewPrev || 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 < mpPolygon->count(), "B2DPolygon access outside range (!)"); + OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B2DPolygon access outside range (!)"); - if(mpPolygon->areControlPointsUsed() && !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 < mpPolygon->count(), "B2DPolygon access outside range (!)"); + OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B2DPolygon access outside range (!)"); - if(mpPolygon->areControlPointsUsed() && !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(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(mpPolygon->count() ? B2DVector(rNextControlPoint - mpPolygon->getPoint(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(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 (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(mpPolygon->getPoint(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(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(mpPolygon->count(), aTempPoly); + mpPolygon->insert(std::as_const(*mpPolygon).count(), aTempPoly); } } void B2DPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount) { - OSL_ENSURE(nIndex + nCount <= 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(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 78b3b7085303..34ff30877ea8 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 < 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 <= 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(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 <= 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(mpPolyPolygon->count(), rPolyPolygon); + mpPolyPolygon->insert(std::as_const(*mpPolyPolygon).count(), rPolyPolygon); } void B2DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount) { - OSL_ENSURE(nIndex + nCount <= 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(mpPolyPolygon->count()) + if(std::as_const(*mpPolyPolygon).count()) { mpPolyPolygon->flip(); } @@ -389,7 +389,7 @@ namespace basegfx void B2DPolyPolygon::transform(const B2DHomMatrix& rMatrix) { - if(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 364f9f8c0e1d..dac943c79049 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 < 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 < mpPolygon->count(), "B3DPolygon access outside range (!)"); + OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B3DPolygon access outside range (!)"); - if(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(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 < mpPolygon->count(), "B3DPolygon access outside range (!)"); + OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B3DPolygon access outside range (!)"); - if(mpPolygon->getNormal(nIndex) != rValue) + if(std::as_const(*mpPolygon).getNormal(nIndex) != rValue) mpPolygon->setNormal(nIndex, rValue); } void B3DPolygon::transformNormals(const B3DHomMatrix& rMatrix) { - if(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(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 < mpPolygon->count(), "B3DPolygon access outside range (!)"); + OSL_ENSURE(nIndex < std::as_const(*mpPolygon).count(), "B3DPolygon access outside range (!)"); - if(mpPolygon->getTextureCoordinate(nIndex) != rValue) + if(std::as_const(*mpPolygon).getTextureCoordinate(nIndex) != rValue) mpPolygon->setTextureCoordinate(nIndex, rValue); } void B3DPolygon::transformTextureCoordinates(const B2DHomMatrix& rMatrix) { - if(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(mpPolygon->areTextureCoordinatesUsed()) + if(std::as_const(*mpPolygon).areTextureCoordinatesUsed()) mpPolygon->clearTextureCoordinates(); } void B3DPolygon::append(const basegfx::B3DPoint& rPoint, sal_uInt32 nCount) { if(nCount) - mpPolygon->insert(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(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(mpPolygon->count(), aTempPoly); + mpPolygon->insert(std::as_const(*mpPolygon).count(), aTempPoly); } } void B3DPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount) { - OSL_ENSURE(nIndex + nCount <= 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(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 97ed39c87718..4104d2fc29fe 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 < 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(mpPolyPolygon->count(), rPolygon, nCount); + mpPolyPolygon->insert(std::as_const(*mpPolyPolygon).count(), rPolygon, nCount); } void B3DPolyPolygon::append(const B3DPolyPolygon& rPolyPolygon) { if(rPolyPolygon.count()) - mpPolyPolygon->insert(mpPolyPolygon->count(), rPolyPolygon); + mpPolyPolygon->insert(std::as_const(*mpPolyPolygon).count(), rPolyPolygon); } void B3DPolyPolygon::remove(sal_uInt32 nIndex, sal_uInt32 nCount) { - OSL_ENSURE(nIndex + nCount <= 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(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 new file mode 100644 index 000000000000..4c04674f65c1 --- /dev/null +++ b/compilerplugins/clang/cow_wrapper.cxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * Based on LLVM/Clang. + * + * This file is distributed under the University of Illinois Open Source + * License. See LICENSE.TXT for details. + * + */ +#ifndef LO_CLANG_SHARED_PLUGINS + +#include <cassert> +#include <string> +#include <iostream> +#include <fstream> +#include <set> +#include <unordered_set> +#include "plugin.hxx" +#include "check.hxx" + +/* +Look for places where we are using cow_wrapper, but we are calling a const method on the impl object +with a non-const pointer, which means we will unnnecessarily trigger a copy. +*/ + +namespace +{ +class Cow_Wrapper : public loplugin::FilteringPlugin<Cow_Wrapper> +{ +public: + explicit Cow_Wrapper(loplugin::InstantiationData const& data) + : FilteringPlugin(data) + { + } + + virtual bool preRun() override { return true; } + + virtual void run() override + { + if (preRun()) + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); + } + + bool VisitCXXMemberCallExpr(const CXXMemberCallExpr*); +}; + +bool Cow_Wrapper::VisitCXXMemberCallExpr(const CXXMemberCallExpr* memberCallExpr) +{ + if (ignoreLocation(memberCallExpr)) + return true; + auto methodDecl = memberCallExpr->getMethodDecl(); + 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) + return true; + + report(DiagnosticsEngine::Warning, + "calling const method on o3tl::cow_wrapper impl class via non-const pointer, rather use " + "std::as_const to prevent triggering an unnecessary copy", + compat::getBeginLoc(memberCallExpr)) + << memberCallExpr->getSourceRange(); + return true; +} + +loplugin::Plugin::Registration<Cow_Wrapper> cow_wrapper("cow_wrapper", true); + +} // namespace + +#endif // LO_CLANG_SHARED_PLUGINS + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/compilerplugins/clang/test/cow_wrapper.cxx b/compilerplugins/clang/test/cow_wrapper.cxx new file mode 100644 index 000000000000..705a4052ef66 --- /dev/null +++ b/compilerplugins/clang/test/cow_wrapper.cxx @@ -0,0 +1,33 @@ +/* -*- 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 "config_clang.h" +#include "o3tl/cow_wrapper.hxx" + +struct ImplBitmapPalette +{ + void foo() const; +}; + +struct BitmapPalette +{ + void foo1() + { + // 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 foo2() const + { + // no error expected + mpImpl->foo(); + } + o3tl::cow_wrapper<ImplBitmapPalette> mpImpl; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/solenv/CompilerTest_compilerplugins_clang.mk b/solenv/CompilerTest_compilerplugins_clang.mk index 768b5a579d04..0bbfcefe9db1 100644 --- a/solenv/CompilerTest_compilerplugins_clang.mk +++ b/solenv/CompilerTest_compilerplugins_clang.mk @@ -25,6 +25,7 @@ $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \ compilerplugins/clang/test/consttobool \ compilerplugins/clang/test/constvars \ compilerplugins/clang/test/convertlong \ + compilerplugins/clang/test/cow_wrapper \ compilerplugins/clang/test/cppunitassertequals \ compilerplugins/clang/test/cstylecast \ compilerplugins/clang/test/datamembershadow \ diff --git a/svx/source/xoutdev/_xpoly.cxx b/svx/source/xoutdev/_xpoly.cxx index f3bb16a1419f..c4d74b996735 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 ) { - 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 ) { - 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 ) { - 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) { - 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) { - 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 275eb5fe97a2..1681159b015a 100644 --- a/vcl/source/font/font.cxx +++ b/vcl/source/font/font.cxx @@ -164,7 +164,7 @@ void Font::SetSymbolFlag( bool bSymbol ) } else { - if ( mpImplFont->GetCharSet() == RTL_TEXTENCODING_SYMBOL ) + if ( std::as_const(*mpImplFont).GetCharSet() == RTL_TEXTENCODING_SYMBOL ) mpImplFont->SetCharSet( RTL_TEXTENCODING_DONTKNOW ); } } @@ -830,9 +830,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( 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, 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(); } |