summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2020-11-18 23:30:24 +0100
committerStephan Bergmann <sbergman@redhat.com>2020-11-19 07:09:58 +0100
commit19926ed35ebb623fc896942b1f232b83edf1fc1e (patch)
treee69e925050fe667aa746494126abfa3336ce16fe /compilerplugins
parent8f79f590662145b054661846e018a4fc1837db8a (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')
-rw-r--r--compilerplugins/clang/stringview.cxx34
-rw-r--r--compilerplugins/clang/test/stringview.cxx8
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: */