compilerplugins/clang/ostr.cxx      |   83 +++++++++++++++++++++++++++++++++++-
 compilerplugins/clang/test/ostr.cxx |   10 ++++
 sw/qa/extras/layout/layout3.cxx     |    9 ++-
 3 files changed, 96 insertions(+), 6 deletions(-)

New commits:
commit f824c4f23c01510b12b53f33778bfa72f7a2ea57
Author:     Stephan Bergmann <stephan.bergm...@allotropia.de>
AuthorDate: Mon Nov 27 21:43:55 2023 +0100
Commit:     Stephan Bergmann <stephan.bergm...@allotropia.de>
CommitDate: Thu Nov 30 14:35:13 2023 +0100

    Extended loplugin:ostr
    
    Change-Id: I987d6d60ca2d1e8ed8b8cde1e0c7996c0fff71b9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160006
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de>

diff --git a/compilerplugins/clang/ostr.cxx b/compilerplugins/clang/ostr.cxx
index da68451e6316..189b74da3152 100644
--- a/compilerplugins/clang/ostr.cxx
+++ b/compilerplugins/clang/ostr.cxx
@@ -352,7 +352,7 @@ public:
         {
             return true;
         }
-        if (!compiler.getDiagnosticOpts().VerifyDiagnostics)
+        if (!compiler.getDiagnosticOpts().VerifyDiagnostics && utf16)
         {
             //TODO: Leave rewriting these uses of ordinary string literals for 
later (but already
             // cover them when verifying CompilerTest_compilerplugins_clang):
@@ -364,7 +364,7 @@ public:
                 Lexer::MeasureTokenLength(l3, compiler.getSourceManager(), 
compiler.getLangOpts()));
             l4 = l4.getLocWithOffset(
                 Lexer::MeasureTokenLength(l4, compiler.getSourceManager(), 
compiler.getLangOpts()));
-            if ((!utf16 || replaceText(l1, delta(l1, l2), macroBegin ? "u\"\" 
" : "u"))
+            if (replaceText(l1, delta(l1, l2), utf16 ? (macroBegin ? "u\"\" " 
: "u") : "")
                 && replaceText(l3, delta(l3, l4),
                                utf16 ? (macroEnd ? " \"\"_ustr" : "_ustr")
                                      : (macroEnd ? " \"\"_ostr" : "_ostr")))
@@ -380,6 +380,85 @@ public:
         return true;
     }
 
+    bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr const* expr)
+    {
+        if (ignoreLocation(expr))
+        {
+            return true;
+        }
+        if (expr->getOperator() != OO_Equal)
+        {
+            return true;
+        }
+        if (!loplugin::TypeCheck(expr->getArg(0)->getType())
+                 .Class("OString")
+                 .Namespace("rtl")
+                 .GlobalNamespace())
+        {
+            return true;
+        }
+        auto const e2 = 
dyn_cast<clang::StringLiteral>(expr->getArg(1)->IgnoreParenImpCasts());
+        if (e2 == nullptr)
+        {
+            return true;
+        }
+        if (rewriter != nullptr)
+        {
+            auto loc = e2->getEndLoc();
+            auto const macroEnd = loc.isMacroID()
+                                  && Lexer::isAtEndOfMacroExpansion(
+                                         loc, compiler.getSourceManager(), 
compiler.getLangOpts());
+            if (macroEnd)
+            {
+                loc = 
compiler.getSourceManager().getImmediateMacroCallerLoc(loc);
+            }
+            if (insertTextAfterToken(loc, macroEnd ? " \"\"_ostr" : "_ostr"))
+            {
+                return true;
+            }
+        }
+        report(DiagnosticsEngine::Warning,
+               "use a _ostr user-defined string literal instead of assigning 
from an ordinary"
+               " string literal",
+               expr->getExprLoc())
+            << expr->getSourceRange();
+        return true;
+    }
+
+    bool VisitCXXMemberCallExpr(CXXMemberCallExpr const* expr)
+    {
+        if (ignoreLocation(expr))
+        {
+            return true;
+        }
+        if (!loplugin::DeclCheck(expr->getMethodDecl()).Operator(OO_Equal))
+        {
+            return true;
+        }
+        if (!loplugin::TypeCheck(expr->getObjectType())
+                 .Class("OString")
+                 .Namespace("rtl")
+                 .GlobalNamespace())
+        {
+            return true;
+        }
+        auto const e2 = 
dyn_cast<clang::StringLiteral>(expr->getArg(0)->IgnoreParenImpCasts());
+        if (e2 == nullptr)
+        {
+            return true;
+        }
+        if (rewriter != nullptr)
+        {
+            //TODO
+        }
+        report(DiagnosticsEngine::Warning,
+               "use a _ostr user-defined string literal instead of assigning 
from an ordinary"
+               " string literal",
+               expr->getExprLoc())
+            << expr->getSourceRange();
+        return true;
+    }
+
     bool VisitCastExpr(CastExpr const* expr)
     {
         if (ignoreLocation(expr))
diff --git a/compilerplugins/clang/test/ostr.cxx 
b/compilerplugins/clang/test/ostr.cxx
index 8e772b1258a2..e6e3a9b556e2 100644
--- a/compilerplugins/clang/test/ostr.cxx
+++ b/compilerplugins/clang/test/ostr.cxx
@@ -112,6 +112,16 @@ void f()
     // expected-error-re@+1 {{use a _ustr user-defined string literal instead 
of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string 
literal [loplugin:ostr]}}
     takeOustring((("foo")));
 
+    OString s9;
+    // expected-error@+1 {{use a _ostr user-defined string literal instead of 
assigning from an ordinary string literal [loplugin:ostr]}}
+    s9 = "foo";
+    // expected-error@+1 {{use a _ostr user-defined string literal instead of 
assigning from an ordinary string literal [loplugin:ostr]}}
+    s9 = (("foo"));
+    // expected-error@+1 {{use a _ostr user-defined string literal instead of 
assigning from an ordinary string literal [loplugin:ostr]}}
+    s9.operator=("foo");
+    // expected-error@+1 {{use a _ostr user-defined string literal instead of 
assigning from an ordinary string literal [loplugin:ostr]}}
+    s9.operator=((("foo")));
+
     // expected-error-re@+1 {{use a _ustr user-defined string literal instead 
of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string 
literal [loplugin:ostr]}}
     S s10 = { "foo" };
 
diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx
index f919a6452912..5401cef9a380 100644
--- a/sw/qa/extras/layout/layout3.cxx
+++ b/sw/qa/extras/layout/layout3.cxx
@@ -216,23 +216,24 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158333)
 
     // shrink line 2
     assertXPath(
-        pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[2]", 
"portion",
+        pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[2]"_ostr, 
"portion"_ostr,
         "viverra odio. Donec auctor molestie sem, sit amet tristique lectus 
hendrerit sed. ");
 
     // shrink line 7
     assertXPath(
-        pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[7]", 
"portion",
+        pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[7]"_ostr, 
"portion"_ostr,
         // This was "...diam ", not "...diam tempor "
         "laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu ut 
diam tempor ");
 
     // shrink line 2 of paragraph 2
     assertXPath(
-        pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[2]", 
"portion",
+        pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[2]"_ostr, 
"portion"_ostr,
         // This was "...Cras ", not "...Cras sodales "
         "Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. 
Cras sodales ");
 
     // shrink line 2 of paragraph 4
-    assertXPath(pXmlDoc, 
"/root/page/body/txt[4]/SwParaPortion/SwLineLayout[2]", "portion",
+    assertXPath(pXmlDoc, 
"/root/page/body/txt[4]/SwParaPortion/SwLineLayout[2]"_ostr,
+                "portion"_ostr,
                 // This was "...et ", not "...et magnis "
                 "consequat arcu ut diam tempor luctus. Cum sociis natoque 
penatibus et magnis ");
 }

Reply via email to