diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2020-11-18 23:30:24 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2020-11-19 07:09:58 +0100 |
commit | 19926ed35ebb623fc896942b1f232b83edf1fc1e (patch) | |
tree | e69e925050fe667aa746494126abfa3336ce16fe /compilerplugins/clang | |
parent | 8f79f590662145b054661846e018a4fc1837db8a (diff) |
loplugin:stringview: Flag empty string converted to string view
Change-Id: Idf412dc5f235230512160cb4fb7e1a00baa1cfa7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106085
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins/clang')
-rw-r--r-- | compilerplugins/clang/stringview.cxx | 34 | ||||
-rw-r--r-- | compilerplugins/clang/test/stringview.cxx | 8 |
2 files changed, 42 insertions, 0 deletions
diff --git a/compilerplugins/clang/stringview.cxx b/compilerplugins/clang/stringview.cxx index 530cf43d95a0..5a70d01de841 100644 --- a/compilerplugins/clang/stringview.cxx +++ b/compilerplugins/clang/stringview.cxx @@ -52,6 +52,7 @@ public: bool VisitCXXConstructExpr(CXXConstructExpr const*); bool VisitFunctionDecl(FunctionDecl const*); bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr const*); + bool VisitImplicitCastExpr(ImplicitCastExpr const*); }; bool StringView::VisitCallExpr(CallExpr const* callExpr) @@ -180,6 +181,39 @@ bool StringView::VisitCXXConstructExpr(CXXConstructExpr const* constructExpr) return true; } +bool StringView::VisitImplicitCastExpr(ImplicitCastExpr const* expr) +{ + if (ignoreLocation(expr)) + { + return true; + } + if (!loplugin::TypeCheck(expr->getType()).ClassOrStruct("basic_string_view").StdNamespace()) + { + return true; + } + auto const e = dyn_cast<CXXConstructExpr>(expr->getSubExprAsWritten()->IgnoreParens()); + if (e == nullptr) + { + return true; + } + if (e->getNumArgs() != 0) + { + return true; + } + auto const tc = loplugin::TypeCheck(e->getType()); + if (!(tc.Class("OString").Namespace("rtl").GlobalNamespace() + || tc.Class("OUString").Namespace("rtl").GlobalNamespace())) + { + return true; + } + report(DiagnosticsEngine::Warning, + "instead of an empty %0, pass an empty '%select{std::string_view|std::u16string_view}1'", + e->getLocation()) + << e->getType() << (tc.Class("OString").Namespace("rtl").GlobalNamespace() ? 0 : 1) + << e->getSourceRange(); + return true; +} + loplugin::Plugin::Registration<StringView> stringview("stringview"); } diff --git a/compilerplugins/clang/test/stringview.cxx b/compilerplugins/clang/test/stringview.cxx index 96d4927e533a..3c15d9cc4437 100644 --- a/compilerplugins/clang/test/stringview.cxx +++ b/compilerplugins/clang/test/stringview.cxx @@ -93,4 +93,12 @@ void f4(OUString s1, OUString s2) } } +void f5() +{ + // expected-error@+1 {{instead of an empty 'rtl::OString', pass an empty 'std::string_view' [loplugin:stringview]}} + call_view(OString()); + // expected-error@+1 {{instead of an empty 'rtl::OUString', pass an empty 'std::u16string_view' [loplugin:stringview]}} + call_view(OUString()); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |