From 5fb20ede2fb47ef91d70b49288129adf8015f34b Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Sun, 5 Nov 2023 17:07:52 +0100 Subject: 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 --- compilerplugins/clang/ostr.cxx | 32 ++++++++++++++++++++++++++++++++ compilerplugins/clang/test/ostr.cxx | 23 +++++++++++++++++++++++ 2 files changed, 55 insertions(+) (limited to 'compilerplugins/clang') 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(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 +#include + #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') 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') 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') 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') 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: */ -- cgit