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(-)
New commits: commit ee373f34ae1509e8d9fffaf4b5140ee9c35e8d41 Author: Stephan Bergmann <sberg...@redhat.com> AuthorDate: Thu Feb 17 19:06:17 2022 +0100 Commit: Stephan Bergmann <sberg...@redhat.com> CommitDate: Thu Feb 17 21:45:49 2022 +0100 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 <sberg...@redhat.com> 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 <sal/config.h> #include <string_view> +#include <utility> #include <rtl/strbuf.hxx> #include <rtl/string.hxx> @@ -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<sal_Int32>(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) {