summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2023-11-05 17:07:52 +0100
committerStephan Bergmann <sbergman@redhat.com>2023-11-05 23:20:55 +0100
commit5fb20ede2fb47ef91d70b49288129adf8015f34b (patch)
treee4911c3717a5288fab4bf8439537c9ed73352424 /compilerplugins
parent1ad81f7e69b545340e340b54f9c9dd387b17cce0 (diff)
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 <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/ostr.cxx32
-rw-r--r--compilerplugins/clang/test/ostr.cxx23
2 files changed, 55 insertions, 0 deletions
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: */