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)
     {

Reply via email to