From ee373f34ae1509e8d9fffaf4b5140ee9c35e8d41 Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Thu, 17 Feb 2022 19:06:17 +0100 Subject: [PATCH] Extend loplugin:stringview to O[U]StringBuffer::makeStringAndClear ...at least when called on an rvalue. (The lvalue case would often be trickier to act upon, if the cleared object is still used later on.) Change-Id: I006e618da004b2127e9ed7381911c2d7b00b1169 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130110 Tested-by: Jenkins Reviewed-by: Stephan Bergmann --- compilerplugins/clang/stringview.cxx | 16 ++++++++++++++ compilerplugins/clang/test/stringview.cxx | 27 +++++++++++++++++++++++ sw/source/filter/ww8/ww8par2.cxx | 5 ++--- 3 files changed, 45 insertions(+), 3 deletions(-) diff --git a/compilerplugins/clang/stringview.cxx b/compilerplugins/clang/stringview.cxx index 1f7783a3f3b3..94ba6f150f1b 100644 --- a/compilerplugins/clang/stringview.cxx +++ b/compilerplugins/clang/stringview.cxx @@ -282,6 +282,22 @@ void StringView::handleCXXMemberCallExpr(CXXMemberCallExpr const* expr) } return; } + if (auto const dc2 = dc1.Function("makeStringAndClear")) + { + if (dc2.Class("OStringBuffer").Namespace("rtl").GlobalNamespace() + || dc2.Class("OUStringBuffer").Namespace("rtl").GlobalNamespace()) + { + auto const obj = expr->getImplicitObjectArgument(); + if (!(obj->isLValue() || obj->getType()->isPointerType())) + { + report(DiagnosticsEngine::Warning, + "rather than call makeStringAndClear on an rvalue, pass with a view", + expr->getExprLoc()) + << expr->getSourceRange(); + } + } + return; + } if (auto const dc2 = dc1.Function("toString")) { if (dc2.Class("OStringBuffer").Namespace("rtl").GlobalNamespace() diff --git a/compilerplugins/clang/test/stringview.cxx b/compilerplugins/clang/test/stringview.cxx index a679ec59ea45..7e637175e259 100644 --- a/compilerplugins/clang/test/stringview.cxx +++ b/compilerplugins/clang/test/stringview.cxx @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -81,6 +82,32 @@ void f1(OStringBuffer s1) // expected-error@+1 {{rather than call toString, pass with a view [loplugin:stringview]}} ConstructWithView(s1.toString()); } +void makeStringAndClear(OUStringBuffer s) +{ + call_view(s.makeStringAndClear()); + ConstructWithView(s.makeStringAndClear()); + call_view((&s)->makeStringAndClear()); + ConstructWithView((&s)->makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + call_view(std::move(s).makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + ConstructWithView(std::move(s).makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + call_view((s).copy(1).makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + ConstructWithView(s.copy(1).makeStringAndClear()); +} +void makeStringAndClear(OStringBuffer s) +{ + call_view(s.makeStringAndClear()); + ConstructWithView(s.makeStringAndClear()); + call_view((&s)->makeStringAndClear()); + ConstructWithView((&s)->makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + call_view(std::move(s).makeStringAndClear()); + // expected-error@+1 {{rather than call makeStringAndClear on an rvalue, pass with a view [loplugin:stringview]}} + ConstructWithView(std::move(s).makeStringAndClear()); +} } namespace test2 diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx index d3df4f76656f..b7ce97387f59 100644 --- a/sw/source/filter/ww8/ww8par2.cxx +++ b/sw/source/filter/ww8/ww8par2.cxx @@ -636,7 +636,7 @@ void SwWW8ImplReader::SetAnlvStrings(SwNumFormat &rNum, int nLevel, WW8_ANLV con bool bListSymbol = pF && ( pF->aFFNBase.chs == 2 ); // Symbol/WingDings/... sal_uInt32 nLen = rAV.cbTextBefore + rAV.cbTextAfter; - OUStringBuffer sText(nLen); + OUStringBuffer sText(static_cast(nLen)); if (m_bVer67) { if (nLen > nElements) @@ -725,8 +725,7 @@ void SwWW8ImplReader::SetAnlvStrings(SwNumFormat &rNum, int nLevel, WW8_ANLV con } if( rAV.cbTextAfter ) { - sSuffix = rNum.GetSuffix(); - sSuffix += sText.copy( rAV.cbTextBefore, rAV.cbTextAfter).makeStringAndClear(); + sSuffix = rNum.GetSuffix() + sText.subView( rAV.cbTextBefore, rAV.cbTextAfter); } if (rAV.cbTextBefore || rAV.cbTextAfter) {