basic/source/uno/namecont.cxx | 2 - compilerplugins/clang/bufferadd.cxx | 38 +++++++++++++++++++++++++++- compilerplugins/clang/test/bufferadd.cxx | 6 ++++ sdext/source/pdfimport/wrapper/wrapper.cxx | 3 -- svgio/source/svgreader/svgtools.cxx | 2 - sw/source/filter/ww8/rtfattributeoutput.cxx | 2 - vcl/unx/generic/printer/ppdparser.cxx | 19 ++++++-------- 7 files changed, 56 insertions(+), 16 deletions(-)
New commits: commit fbe05bc89a53f4c31e5ccf62edb21e83184c0a34 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Wed Apr 16 12:40:19 2025 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Tue Apr 22 11:53:07 2025 +0200 loplugin:bufferadd extend it to find some more places where we can simplify *StringBuffer usage Change-Id: Ic2005b886b486a6627a43f8dcfba3258cb168921 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184428 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/basic/source/uno/namecont.cxx b/basic/source/uno/namecont.cxx index 8c66cebbbfcf..5436b3c6c380 100644 --- a/basic/source/uno/namecont.cxx +++ b/basic/source/uno/namecont.cxx @@ -1744,7 +1744,7 @@ void SfxLibraryContainer::storeLibraries_Impl( const uno::Reference< embed::XSto if ( bInplaceStorage ) { // create a temporary target storage - const OUStringBuffer aTempTargetNameBase = maLibrariesDir + "_temp_"; + const OUString aTempTargetNameBase = maLibrariesDir + "_temp_"; sal_Int32 index = 0; do { diff --git a/compilerplugins/clang/bufferadd.cxx b/compilerplugins/clang/bufferadd.cxx index 8f58e46aba14..0dd65868f640 100644 --- a/compilerplugins/clang/bufferadd.cxx +++ b/compilerplugins/clang/bufferadd.cxx @@ -119,12 +119,26 @@ bool BufferAdd::VisitCallExpr(CallExpr const* callExpr) if (ignoreLocation(callExpr)) return true; + // calls to "buffer = foo" are OK + // calls to "xxx = foo1 + buffer" are OK + if (auto operatorCall = dyn_cast<CXXOperatorCallExpr>(callExpr)) + { + auto op = operatorCall->getOperator(); + if (op == OO_PlusEqual || op == OO_Equal || op == OO_Plus) + return true; + } + + // exclude buffer vars where the var is passed as a parameter to another function for (unsigned i = 0; i != callExpr->getNumArgs(); ++i) { auto a = ignore(callExpr->getArg(i)); if (auto declRefExpr = dyn_cast<DeclRefExpr>(a)) if (auto varDecl = dyn_cast<VarDecl>(declRefExpr->getDecl())) + { badMap.insert(varDecl); + if (varDecl->getName() == "noelf7") + callExpr->dump(); + } } return true; } @@ -215,6 +229,28 @@ void BufferAdd::findBufferAssignOrAdd(const Stmt* parentStmt, Stmt const* stmt) } } + // check for assignment to string buffer + if (auto operatorCall = dyn_cast<CXXOperatorCallExpr>(stmt)) + { + auto op = operatorCall->getOperator(); + if (op == OO_PlusEqual || op == OO_Equal) + { + if (auto declRefExprLHS = dyn_cast<DeclRefExpr>(ignore(operatorCall->getArg(0)))) + { + if (auto varDeclLHS = dyn_cast<VarDecl>(declRefExprLHS->getDecl())) + { + auto tc = loplugin::TypeCheck(varDeclLHS->getType()); + if (tc.Class("OUStringBuffer").Namespace("rtl").GlobalNamespace() + || tc.Class("OStringBuffer").Namespace("rtl").GlobalNamespace()) + { + addToGoodMap(varDeclLHS, parentStmt); + return; + } + } + } + } + } + // now check for chained append calls auto expr = dyn_cast<Expr>(stmt); @@ -316,7 +352,7 @@ bool BufferAdd::isSideEffectFree(Expr const* expr) if (auto operatorCall = dyn_cast<CXXOperatorCallExpr>(expr)) { auto op = operatorCall->getOperator(); - if (op == OO_PlusEqual || op == OO_Plus) + if (op == OO_PlusEqual || op == OO_Plus || op == OO_Equal) if (isSideEffectFree(operatorCall->getArg(0)) && isSideEffectFree(operatorCall->getArg(1))) return true; diff --git a/compilerplugins/clang/test/bufferadd.cxx b/compilerplugins/clang/test/bufferadd.cxx index c8057a6f497b..464214461083 100644 --- a/compilerplugins/clang/test/bufferadd.cxx +++ b/compilerplugins/clang/test/bufferadd.cxx @@ -111,6 +111,12 @@ void f6() while (true) noel1.append("ffff").append("aaa"); } +void f7() +{ + // expected-error@+1 {{convert this append sequence into a *String + sequence [loplugin:bufferadd]}} + OStringBuffer noelf7("xxx"); + noelf7 = "xxx" + noelf7 + "xxx"; +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sdext/source/pdfimport/wrapper/wrapper.cxx b/sdext/source/pdfimport/wrapper/wrapper.cxx index 461681439be4..fcac1cdacfa2 100644 --- a/sdext/source/pdfimport/wrapper/wrapper.cxx +++ b/sdext/source/pdfimport/wrapper/wrapper.cxx @@ -1097,9 +1097,8 @@ bool xpdf_ImportFromFile(const OUString& rURL, bool bEntered = false; do { - OStringBuffer aBuf(256); // Password lines are Pmypassword followed by "O " to try to open - aBuf = "P" + OUStringToOString(aPwd, RTL_TEXTENCODING_ISO_8859_1) + " O "; + OString aBuf = "P" + OUStringToOString(aPwd, RTL_TEXTENCODING_ISO_8859_1) + " O "; osl_writeFile(pIn, aBuf.getStr(), sal_uInt64(aBuf.getLength()), &nWritten); diff --git a/svgio/source/svgreader/svgtools.cxx b/svgio/source/svgreader/svgtools.cxx index 3918660fb7bd..d2795198504b 100644 --- a/svgio/source/svgreader/svgtools.cxx +++ b/svgio/source/svgreader/svgtools.cxx @@ -407,7 +407,7 @@ namespace svgio::svgreader // by error. First try if there are numbers after the 'e', // safe current state nPos++; - const OUStringBuffer aNum2(aNum); + const OUString aNum2(aNum); const sal_Int32 nPosAfterE(nPos); aNum.append(aChar); diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index abda306d67cb..9e832a45c9a7 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -1988,7 +1988,7 @@ void RtfAttributeOutput::WriteAnnotationMarks_Impl(std::vector<ReferenceMarkerNa void RtfAttributeOutput::WriteHeaderFooter_Impl(const SwFrameFormat& rFormat, bool bHeader, const char* pStr, bool bTitlepg) { - OStringBuffer aSectionBreaks = m_aSectionBreaks; + OString aSectionBreaks = m_aSectionBreaks.toString(); m_aSectionBreaks.setLength(0); RtfStringBuffer aRun = m_aRun; m_aRun.clear(); diff --git a/vcl/unx/generic/printer/ppdparser.cxx b/vcl/unx/generic/printer/ppdparser.cxx index b6c25830fd37..c68e285b0433 100644 --- a/vcl/unx/generic/printer/ppdparser.cxx +++ b/vcl/unx/generic/printer/ppdparser.cxx @@ -635,18 +635,17 @@ PPDParser::PPDParser(OUString aFile, const std::vector<PPDKey*>& keys) OString o = OUStringToOString( aValueName, aEncoding ); pwg_media_t *pPWGMedia = pwgMediaForPWG(o.pData->buffer); if (pPWGMedia != nullptr) { - OUStringBuffer aBuf( 256 ); - aBuf = "0 0 " + - OUString::number(PWG_TO_POINTS(pPWGMedia -> width)) + - " " + - OUString::number(PWG_TO_POINTS(pPWGMedia -> length)); if ( pImageableAreaValue ) - pImageableAreaValue->m_aValue = aBuf.makeStringAndClear(); - aBuf.append( OUString::number(PWG_TO_POINTS(pPWGMedia -> width)) - + " " - + OUString::number(PWG_TO_POINTS(pPWGMedia -> length) )); + pImageableAreaValue->m_aValue = + "0 0 " + + OUString::number(PWG_TO_POINTS(pPWGMedia -> width)) + + " " + + OUString::number(PWG_TO_POINTS(pPWGMedia -> length)); if ( pPaperDimensionValue ) - pPaperDimensionValue->m_aValue = aBuf.makeStringAndClear(); + pPaperDimensionValue->m_aValue = + OUString::number(PWG_TO_POINTS(pPWGMedia -> width)) + + " " + + OUString::number(PWG_TO_POINTS(pPWGMedia -> length)); if (aValueName.equals(pKey -> getDefaultValue() -> m_aOption)) { pImageableAreas -> m_pDefaultValue = pImageableAreaValue; pPaperDimensions -> m_pDefaultValue = pPaperDimensionValue;