From 56e6f0da839c53867947d1e06f0e733022df7d0e Mon Sep 17 00:00:00 2001 From: Noel Grandin Date: Fri, 4 Sep 2015 12:16:17 +0200 Subject: new loplugin: badvectorinit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit look for places calling the 1-argument vector fill constructor and then immediately called push_back, which is generally a sign that its leaving empty slots. Change-Id: I34e69b8d09cc48c0d409499faaf192b9f86bc517 Reviewed-on: https://gerrit.libreoffice.org/17525 Reviewed-by: Björn Michaelsen Tested-by: Björn Michaelsen --- chart2/source/view/charttypes/AreaChart.cxx | 6 +- chart2/source/view/charttypes/NetChart.cxx | 6 +- compilerplugins/clang/badvectorinit.cxx | 214 +++++++++++++++++++++ .../source/drivers/calc/CDatabaseMetaData.cxx | 4 +- .../source/drivers/file/FDatabaseMetaData.cxx | 2 +- .../drivers/mork/MDatabaseMetaDataHelper.cxx | 2 +- .../propctrlr/xsdvalidationpropertyhandler.cxx | 2 +- filter/source/svg/svgreader.cxx | 2 +- mysqlc/source/mysqlc_databasemetadata.cxx | 30 +-- sax/qa/cppunit/test_converter.cxx | 4 +- sw/source/core/layout/paintfrm.cxx | 2 +- 11 files changed, 245 insertions(+), 29 deletions(-) create mode 100644 compilerplugins/clang/badvectorinit.cxx diff --git a/chart2/source/view/charttypes/AreaChart.cxx b/chart2/source/view/charttypes/AreaChart.cxx index c7d9f70f5ef1..f6f6d7b17d90 100644 --- a/chart2/source/view/charttypes/AreaChart.cxx +++ b/chart2/source/view/charttypes/AreaChart.cxx @@ -592,13 +592,15 @@ namespace void lcl_reorderSeries( ::std::vector< ::std::vector< VDataSeriesGroup > >& rZSlots ) { - ::std::vector< ::std::vector< VDataSeriesGroup > > aRet( rZSlots.size() ); + ::std::vector< ::std::vector< VDataSeriesGroup > > aRet; + aRet.reserve( rZSlots.size() ); ::std::vector< ::std::vector< VDataSeriesGroup > >::reverse_iterator aZIt( rZSlots.rbegin() ); ::std::vector< ::std::vector< VDataSeriesGroup > >::reverse_iterator aZEnd( rZSlots.rend() ); for( ; aZIt != aZEnd; ++aZIt ) { - ::std::vector< VDataSeriesGroup > aXSlot( aZIt->size() ); + ::std::vector< VDataSeriesGroup > aXSlot; + aXSlot.reserve( aZIt->size() ); ::std::vector< VDataSeriesGroup >::reverse_iterator aXIt( aZIt->rbegin() ); ::std::vector< VDataSeriesGroup >::reverse_iterator aXEnd( aZIt->rend() ); diff --git a/chart2/source/view/charttypes/NetChart.cxx b/chart2/source/view/charttypes/NetChart.cxx index 1c0d2cd6bbe8..664c2dcdd5b7 100644 --- a/chart2/source/view/charttypes/NetChart.cxx +++ b/chart2/source/view/charttypes/NetChart.cxx @@ -297,13 +297,15 @@ namespace void lcl_reorderSeries( ::std::vector< ::std::vector< VDataSeriesGroup > >& rZSlots ) { - ::std::vector< ::std::vector< VDataSeriesGroup > > aRet( rZSlots.size() ); + ::std::vector< ::std::vector< VDataSeriesGroup > > aRet; + aRet.reserve( rZSlots.size() ); ::std::vector< ::std::vector< VDataSeriesGroup > >::reverse_iterator aZIt( rZSlots.rbegin() ); ::std::vector< ::std::vector< VDataSeriesGroup > >::reverse_iterator aZEnd( rZSlots.rend() ); for( ; aZIt != aZEnd; ++aZIt ) { - ::std::vector< VDataSeriesGroup > aXSlot( aZIt->size() ); + ::std::vector< VDataSeriesGroup > aXSlot; + aXSlot.reserve( aZIt->size() ); ::std::vector< VDataSeriesGroup >::reverse_iterator aXIt( aZIt->rbegin() ); ::std::vector< VDataSeriesGroup >::reverse_iterator aXEnd( aZIt->rend() ); diff --git a/compilerplugins/clang/badvectorinit.cxx b/compilerplugins/clang/badvectorinit.cxx new file mode 100644 index 000000000000..005726e8d02a --- /dev/null +++ b/compilerplugins/clang/badvectorinit.cxx @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include +#include +#include +#include +#include +#include "plugin.hxx" +#include "compat.hxx" + +/** + +Comments from Bjoern Michaelsen: + +Killing the 1-argument vector fill constructor: + + std::vector< basebmp::Color > aDevPal(2); + +in general is probably a Good Thing(tm). It can just be too misleading. +Requiring at least the explicit two-value fill constructor for the rare cases where +someone wants a filled vector isnt too much to ask and less prone to +misunderstandings: + + std::vector< basebmp::Color > aDevPal(2, basebmp::Color(0,0,0)); + +Although that _still_ might be misleading[1], so turning all those into the +somewhat longer, but more explicit: + + std::vector< basebmp::Color > aDevPal; + aDevPal.reserve(2); + aDevPal.push_back(...); + ... + +> So I suppose the check would be for a size reservation on a vector +> followed by push_back - rather than some array indexing - does that make +> sense ? or did I go crazy ;-) + +Yes, in general you want neither of the above forms. Preferably instead of +e.g.: + + std::vector< basebmp::Color > aDevPal(2); + aDevPal[0] = basebmp::Color( 0, 0, 0 ); + aDevPal[1] = basebmp::Color( 0xff, 0xff, 0xff ); + +you would -- if possible -- simply: + + std::vector< basebmp::Color > aDevPal{ + basebmp::Color( 0, 0, 0 ), + basebmp::Color( 0xff, 0xff, 0xff ) }; + +and only for complex cases, where you do not have the elements statically +available, something like: + + std::vector< foo > vFoos; + vFoos.reserve(vInput.size()); + std::transform(std::back_inserter(vFoos), + vInput.begin(), + vInput.end(), + [] (decltype(vInput)::value_type aInputValue) { return do_something(aInputValue); }); + +see also: +https://skyfromme.wordpress.com/2015/03/02/50-ways-to-fill-your-vector/ +https://skyfromme.wordpress.com/2015/03/12/following-the-white-rabbit/ +(tl;dr: Use initializer lists to fill vectors when possible). + +Best, + +Bjoern + +[1] Well, except that: + std::vector(3, 0) + is doing something different from: + std::vector{3, 0} + just to make things more interesting. But hey, that's C++ for you. + But that wart exists for the 1-arg ctor too -- yet another reason to kill that. +*/ + +namespace { + + +class BadVectorInit: + public RecursiveASTVisitor, public loplugin::Plugin +{ +public: + explicit BadVectorInit(InstantiationData const & data): Plugin(data) {} + + virtual void run() override + { + TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); + } + + bool VisitCXXConstructExpr(const CXXConstructExpr* ); + bool TraverseFunctionDecl(FunctionDecl* ); + bool VisitCXXMemberCallExpr(const CXXMemberCallExpr* ); +private: + StringRef getFilename(SourceLocation loc); + bool mbInsideFunction; + std::set suspectSet; +}; + +bool BadVectorInit::TraverseFunctionDecl(FunctionDecl* decl) +{ + mbInsideFunction = true; + bool ret = RecursiveASTVisitor::TraverseFunctionDecl(decl); + mbInsideFunction = false; + suspectSet.clear(); + return ret; +} + +StringRef BadVectorInit::getFilename(SourceLocation loc) +{ + SourceLocation spellingLocation = compiler.getSourceManager().getSpellingLoc(loc); + StringRef name { compiler.getSourceManager().getFilename(spellingLocation) }; + return name; +} + +bool BadVectorInit::VisitCXXMemberCallExpr(const CXXMemberCallExpr* expr) +{ + if (suspectSet.empty() || ignoreLocation( expr )) + return true; + + // need to exclude some false positives + StringRef aFileName = getFilename(expr->getLocStart()); + if (aFileName == SRCDIR "/framework/source/services/autorecovery.cxx" + || aFileName == SRCDIR "/vcl/source/opengl/OpenGLHelper.cxx" + || aFileName == SRCDIR "/vcl/source/gdi/gdimtf.cxx" + ) + { + return true; + } + + const FunctionDecl* functionDecl = expr->getDirectCallee(); + if (!functionDecl) + return true; + if (functionDecl->getNameAsString().find("push_back") == string::npos) + return true; + const DeclRefExpr* declExpr = dyn_cast(expr->getImplicitObjectArgument()); + if (!declExpr) + return true; + const VarDecl* varDecl = dyn_cast(declExpr->getDecl()); + if (!varDecl) + return true; + varDecl = varDecl->getCanonicalDecl(); + if (suspectSet.find(varDecl) == suspectSet.end()) + return true; + report( + DiagnosticsEngine::Warning, + "calling push_back after using sized constructor", + expr->getLocStart()) + << expr->getSourceRange(); + report( + DiagnosticsEngine::Note, + "on this var", + varDecl->getLocStart()) + << varDecl->getSourceRange(); + + return true; +} + +bool BadVectorInit::VisitCXXConstructExpr(const CXXConstructExpr* expr) +{ + if (ignoreLocation( expr )) + return true; + + const CXXConstructorDecl *consDecl = expr->getConstructor(); + consDecl = consDecl->getCanonicalDecl(); + + if (consDecl->param_size() == 0) + return true; + + std::string aParentName = consDecl->getParent()->getQualifiedNameAsString(); + if (aParentName.find("vector") == string::npos && aParentName.find("deque") == string::npos) + return true; + + // ignore the copy constructor + const ParmVarDecl* pParam = consDecl->getParamDecl(0); + std::string aParam1 = pParam->getOriginalType().getAsString(); + if (aParam1.find("vector") != string::npos + || aParam1.find("deque") != string::npos + || aParam1.find("initializer_list") != string::npos + || aParam1.find("iterator") != string::npos) + return true; + + // found a call to the 1-arg vector constructor, now look for the VarDecl it belongs to + + const Stmt* parent = expr; + do { + parent = parentStmt(parent); + if (!parent) break; + if (isa(parent)) + { + const DeclStmt* declStmt = dyn_cast(parent); + const Decl* decl = declStmt->getSingleDecl(); + if (decl && isa(decl)) + suspectSet.insert(dyn_cast(decl)->getCanonicalDecl()); + break; + } + } while (true); + + return true; +} + +loplugin::Plugin::Registration< BadVectorInit > X("badvectorinit", true); + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/connectivity/source/drivers/calc/CDatabaseMetaData.cxx b/connectivity/source/drivers/calc/CDatabaseMetaData.cxx index dc15b2b25948..1cf99631b348 100644 --- a/connectivity/source/drivers/calc/CDatabaseMetaData.cxx +++ b/connectivity/source/drivers/calc/CDatabaseMetaData.cxx @@ -399,7 +399,7 @@ Reference< XResultSet > SAL_CALL OCalcDatabaseMetaData::getTables( OUString aName = aSheetNames[nSheet]; if ( !lcl_IsEmptyOrHidden( xSheets, aName ) && match(tableNamePattern,aName,'\0') ) { - ODatabaseMetaDataResultSet::ORow aRow(3); + ODatabaseMetaDataResultSet::ORow aRow { NULL, NULL, NULL }; aRow.reserve(6); aRow.push_back(new ORowSetValueDecorator(aName)); aRow.push_back(new ORowSetValueDecorator(aTable)); @@ -424,7 +424,7 @@ Reference< XResultSet > SAL_CALL OCalcDatabaseMetaData::getTables( OUString aName = aDBNames[nRange]; if ( !lcl_IsUnnamed( xRanges, aName ) && match(tableNamePattern,aName,'\0') ) { - ODatabaseMetaDataResultSet::ORow aRow(3); + ODatabaseMetaDataResultSet::ORow aRow { NULL, NULL, NULL }; aRow.reserve(6); aRow.push_back(new ORowSetValueDecorator(aName)); aRow.push_back(new ORowSetValueDecorator(aTable)); diff --git a/connectivity/source/drivers/file/FDatabaseMetaData.cxx b/connectivity/source/drivers/file/FDatabaseMetaData.cxx index f75db5a41e68..ecc80c022ef1 100644 --- a/connectivity/source/drivers/file/FDatabaseMetaData.cxx +++ b/connectivity/source/drivers/file/FDatabaseMetaData.cxx @@ -225,7 +225,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables( aURL.SetSmartURL( sUrl ); sThisContentExtension = aURL.getExtension(); - ODatabaseMetaDataResultSet::ORow aRow(3); + ODatabaseMetaDataResultSet::ORow aRow { NULL, NULL, NULL }; aRow.reserve(6); bool bNewRow = false; diff --git a/connectivity/source/drivers/mork/MDatabaseMetaDataHelper.cxx b/connectivity/source/drivers/mork/MDatabaseMetaDataHelper.cxx index f04f2bf84360..9d6c4e937c25 100644 --- a/connectivity/source/drivers/mork/MDatabaseMetaDataHelper.cxx +++ b/connectivity/source/drivers/mork/MDatabaseMetaDataHelper.cxx @@ -106,7 +106,7 @@ bool MDatabaseMetaDataHelper::getTables( OConnection* _pCon, return false; for ( size_t i = 0; i < tables.size(); i++ ) { - ODatabaseMetaDataResultSet::ORow aRow(3); + ODatabaseMetaDataResultSet::ORow aRow { NULL, NULL, NULL }; OUString aTableName = tables[i]; SAL_INFO("connectivity.mork", "TableName: " << aTableName ); diff --git a/extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx b/extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx index ddcd08345053..214b7df7997d 100644 --- a/extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx +++ b/extensions/source/propctrlr/xsdvalidationpropertyhandler.cxx @@ -262,7 +262,7 @@ namespace pcr Sequence< OUString > SAL_CALL XSDValidationPropertyHandler::getActuatingProperties( ) throw (RuntimeException, std::exception) { ::osl::MutexGuard aGuard( m_aMutex ); - ::std::vector< OUString > aInterestedInActuations( 2 ); + ::std::vector< OUString > aInterestedInActuations; if ( m_pHelper.get() ) { aInterestedInActuations.push_back( OUString(PROPERTY_XSD_DATA_TYPE) ); diff --git a/filter/source/svg/svgreader.cxx b/filter/source/svg/svgreader.cxx index aeb3793252a2..23e98b87c332 100644 --- a/filter/source/svg/svgreader.cxx +++ b/filter/source/svg/svgreader.cxx @@ -341,7 +341,7 @@ struct AnnotatingVisitor return; //easy! :-) // join similar colors - std::vector aNewStops(1,rGradient.maStops.front()); + std::vector aNewStops { rGradient.maStops.front() }; for( sal_Size i=1; i SAL_CALL ODatabaseMetaData::getTableTypes() for (sal_uInt32 i = 0; i < 2; i++) { if (m_rConnection.getMysqlVersion() >= requiredVersion[i]) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(table_types[i], encoding))); rRows.push_back(aRow); } @@ -1097,7 +1097,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTypeInfo() rtl_TextEncoding encoding = m_rConnection.getConnectionEncoding(); unsigned int i = 0; while (mysqlc_types[i].typeName) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(mysqlc_types[i].typeName, encoding))); aRow.push_back(makeAny(mysqlc_types[i].dataType)); @@ -1140,7 +1140,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCatalogs() sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } @@ -1172,7 +1172,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getSchemas() sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; bool informationSchema = false; for (sal_uInt32 i = 1; i <= columns; i++) { sql::SQLString columnStringValue = rset->getString(i); @@ -1219,7 +1219,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumnPrivileges( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } @@ -1261,7 +1261,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getColumns( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { if (i == 5) { // ColumnType sal_Int32 sdbc_type = mysqlc_sdbc_driver::mysqlToOOOType(atoi(rset->getString(i).c_str())); @@ -1317,7 +1317,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTables( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; bool informationSchema = false; for (sal_uInt32 i = 1; (i <= columns) && !informationSchema; ++i) { sql::SQLString columnStringValue = rset->getString(i); @@ -1378,7 +1378,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getProcedures( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } @@ -1428,7 +1428,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getExportedKeys( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } @@ -1467,7 +1467,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getImportedKeys( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } @@ -1505,7 +1505,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getPrimaryKeys( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } @@ -1545,7 +1545,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getIndexInfo( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } @@ -1585,7 +1585,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getBestRowIdentifier( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } @@ -1643,7 +1643,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getTablePrivileges( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } @@ -1688,7 +1688,7 @@ Reference< XResultSet > SAL_CALL ODatabaseMetaData::getCrossReference( sql::ResultSetMetaData * rs_meta = rset->getMetaData(); sal_uInt32 columns = rs_meta->getColumnCount(); while (rset->next()) { - std::vector< Any > aRow(1); + std::vector< Any > aRow { Any() }; for (sal_uInt32 i = 1; i <= columns; i++) { aRow.push_back(makeAny(mysqlc_sdbc_driver::convert(rset->getString(i), encoding))); } diff --git a/sax/qa/cppunit/test_converter.cxx b/sax/qa/cppunit/test_converter.cxx index 67290d59facd..1e3061e8090f 100644 --- a/sax/qa/cppunit/test_converter.cxx +++ b/sax/qa/cppunit/test_converter.cxx @@ -664,9 +664,7 @@ void doTestDecodeBase64(const uno::Sequence& aPass, char const*const p void ConverterTest::testBase64() { - std::vector< sal_Int8 > tempSeq(4); - for(sal_Int8 i = 0; i<4; ++i) - tempSeq.push_back(i); + std::vector< sal_Int8 > tempSeq { 0, 0, 0, 0, 0, 1, 2, 3 }; uno::Sequence< sal_Int8 > tempSequence = comphelper::containerToSequence(tempSeq); doTestEncodeBase64("AAAAAAABAgM=", tempSequence); doTestDecodeBase64(tempSequence, "AAAAAAABAgM="); diff --git a/sw/source/core/layout/paintfrm.cxx b/sw/source/core/layout/paintfrm.cxx index 31b5dae4fadf..ac06ab9b76ca 100644 --- a/sw/source/core/layout/paintfrm.cxx +++ b/sw/source/core/layout/paintfrm.cxx @@ -4426,7 +4426,7 @@ static void lcl_PaintShadow( const SwRect& rRect, SwRect& rOutRect, const long nWidth = ::lcl_AlignWidth ( rShadow.GetWidth(), properties ); const long nHeight = ::lcl_AlignHeight( rShadow.GetWidth(), properties ); - SwRects aRegion( 2 ); + SwRects aRegion; SwRect aOut( rOutRect ); switch ( rShadow.GetLocation() ) -- cgit