diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2023-11-05 17:07:52 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2023-11-05 23:20:55 +0100 |
commit | 5fb20ede2fb47ef91d70b49288129adf8015f34b (patch) | |
tree | e4911c3717a5288fab4bf8439537c9ed73352424 /compilerplugins | |
parent | 1ad81f7e69b545340e340b54f9c9dd387b17cce0 (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.cxx | 32 | ||||
-rw-r--r-- | compilerplugins/clang/test/ostr.cxx | 23 |
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: */ |