compilerplugins/clang/ostr.cxx      |   32 ++++++++++++++++++++++++++++++++
 compilerplugins/clang/test/ostr.cxx |   23 +++++++++++++++++++++++
 2 files changed, 55 insertions(+)

New commits:
commit 5fb20ede2fb47ef91d70b49288129adf8015f34b
Author:     Stephan Bergmann <sberg...@redhat.com>
AuthorDate: Sun Nov 5 17:07:52 2023 +0100
Commit:     Stephan Bergmann <sberg...@redhat.com>
CommitDate: Sun Nov 5 23:20:55 2023 +0100

    loplugin:ostr: Warn about literals that could be string_view
    
    ...inspired by d4f4a401861e7c908b6ab7f72563d5ab911edcf0 "This function 
takes a
    string view - no need in OUString literal", but this found no further cases
    
    Change-Id: I1429950afdb6fff8ed1d28f5fbb4c445fb6bfb12
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158954
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sberg...@redhat.com>

diff --git a/compilerplugins/clang/ostr.cxx b/compilerplugins/clang/ostr.cxx
index d0290aad1f90..16d8f32dbc0e 100644
--- a/compilerplugins/clang/ostr.cxx
+++ b/compilerplugins/clang/ostr.cxx
@@ -383,6 +383,38 @@ public:
         return true;
     }
 
+    bool VisitCastExpr(CastExpr const* expr)
+    {
+        if (ignoreLocation(expr))
+        {
+            return true;
+        }
+        auto const t1 = expr->getType().getNonReferenceType();
+        auto const tc1 = loplugin::TypeCheck(t1);
+        if (!(tc1.ClassOrStruct("basic_string").StdNamespace()
+              || tc1.ClassOrStruct("basic_string_view").StdNamespace()))
+        {
+            return true;
+        }
+        auto const e2 = 
dyn_cast<UserDefinedLiteral>(expr->getSubExprAsWritten());
+        if (e2 == nullptr)
+        {
+            return true;
+        }
+        auto const tc2 = loplugin::TypeCheck(e2->getType());
+        if (!(tc2.Class("OString").Namespace("rtl").GlobalNamespace()
+              || tc2.Class("OUString").Namespace("rtl").GlobalNamespace()))
+        {
+            return true;
+        }
+        report(DiagnosticsEngine::Warning,
+               "directly use a %0 value instead of a %select{_ostr|_ustr}1 
user-defined string"
+               " literal",
+               expr->getExprLoc())
+            << t1.getUnqualifiedType() << bool(tc2.Class("OUString")) << 
expr->getSourceRange();
+        return true;
+    }
+
 private:
     bool isSpellingRange(SourceLocation loc1, SourceLocation loc2)
     {
diff --git a/compilerplugins/clang/test/ostr.cxx 
b/compilerplugins/clang/test/ostr.cxx
index 28e2d746a447..d8ad56201ec3 100644
--- a/compilerplugins/clang/test/ostr.cxx
+++ b/compilerplugins/clang/test/ostr.cxx
@@ -9,6 +9,9 @@
 
 #include "sal/config.h"
 
+#include <string>
+#include <string_view>
+
 #include "rtl/ustring.hxx"
 
 #define M(arg) f(arg, arg)
@@ -22,6 +25,14 @@ void f(OUString const&);
 
 void f(OUString const&, OUString const&);
 
+void takeStdString(std::string const&);
+
+void takeStdString(std::u16string const&);
+
+void takeStdView(std::string_view);
+
+void takeStdView(std::u16string_view);
+
 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]}}
@@ -72,4 +83,16 @@ void f()
     (void)l4;
 }
 
+void passLiteral()
+{
+    // expected-error@+1 {{directly use a 'std::string' (aka 
'basic_string<char>') value instead of a _ostr user-defined string literal 
[loplugin:ostr]}}
+    takeStdString(std::string(""_ostr));
+    // expected-error@+1 {{directly use a 'std::u16string' (aka 
'basic_string<char16_t>') value instead of a _ustr user-defined string literal 
[loplugin:ostr]}}
+    takeStdString(std::u16string(u""_ustr));
+    // expected-error@+1 {{directly use a 'std::string_view' (aka 
'basic_string_view<char>') value instead of a _ostr user-defined string literal 
[loplugin:ostr]}}
+    takeStdView(""_ostr);
+    // expected-error@+1 {{directly use a 'std::u16string_view' (aka 
'basic_string_view<char16_t>') value instead of a _ustr user-defined string 
literal [loplugin:ostr]}}
+    takeStdView(u""_ustr);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */

Reply via email to