summaryrefslogtreecommitdiff
path: root/compilerplugins/clang/stringview.cxx
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2020-12-04 16:24:56 +0100
committerStephan Bergmann <sbergman@redhat.com>2020-12-04 17:54:48 +0100
commit6c905fb6430b6ec43630e826f9afd935734f4c91 (patch)
tree6fefee2c2004bab1afd12bbb6c951a6b427604cb /compilerplugins/clang/stringview.cxx
parentfcb7fe3a082c200f69f10c1d3951761a7e41d6e0 (diff)
Improve loplugin:stringview detection of unnecessary O[U]String construction
Change-Id: Ia45119e11377e916a1e1deb5648ed9033c417d77 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107228 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins/clang/stringview.cxx')
-rw-r--r--compilerplugins/clang/stringview.cxx74
1 files changed, 69 insertions, 5 deletions
diff --git a/compilerplugins/clang/stringview.cxx b/compilerplugins/clang/stringview.cxx
index 06b2fb8fdf02..26af817659be 100644
--- a/compilerplugins/clang/stringview.cxx
+++ b/compilerplugins/clang/stringview.cxx
@@ -122,21 +122,85 @@ bool StringView::VisitImplicitCastExpr(ImplicitCastExpr const* expr)
{
handleCXXConstructExpr(e1);
}
- else if (auto const e2 = dyn_cast<CXXMemberCallExpr>(e))
+ else if (auto const e2 = dyn_cast<CXXFunctionalCastExpr>(e))
{
- handleCXXMemberCallExpr(e2);
+ auto e3 = e2->getSubExpr();
+ if (auto const e4 = dyn_cast<CXXBindTemporaryExpr>(e3))
+ {
+ e3 = e4->getSubExpr();
+ }
+ if (auto const e4 = dyn_cast<CXXConstructExpr>(e3))
+ {
+ handleCXXConstructExpr(e4);
+ }
+ }
+ else if (auto const e3 = dyn_cast<CXXMemberCallExpr>(e))
+ {
+ handleCXXMemberCallExpr(e3);
}
return true;
}
void StringView::handleCXXConstructExpr(CXXConstructExpr const* expr)
{
- if (expr->getNumArgs() != 0)
+ auto const d = expr->getConstructor();
+ switch (d->getNumParams())
{
- return;
+ case 0:
+ break;
+ case 1:
+ {
+ auto const t = d->getParamDecl(0)->getType();
+ if (t->isAnyCharacterType())
+ {
+ break;
+ }
+ loplugin::TypeCheck tc(t);
+ if (tc.LvalueReference()
+ .Const()
+ .Class("OStringLiteral")
+ .Namespace("rtl")
+ .GlobalNamespace()
+ || tc.LvalueReference()
+ .Const()
+ .Class("OUStringLiteral")
+ .Namespace("rtl")
+ .GlobalNamespace()
+ || tc.RvalueReference().Struct("OStringNumber").Namespace("rtl").GlobalNamespace()
+ || tc.RvalueReference().Struct("OUStringNumber").Namespace("rtl").GlobalNamespace()
+ || tc.ClassOrStruct("basic_string_view").StdNamespace())
+ {
+ break;
+ }
+ return;
+ }
+ case 2:
+ {
+ auto const t0 = d->getParamDecl(0)->getType();
+ if (t0->isPointerType() && t0->getPointeeType()->isAnyCharacterType())
+ {
+ auto const t = d->getParamDecl(1)->getType();
+ if (t->isIntegralType(compiler.getASTContext())
+ && !(t->isBooleanType() || t->isAnyCharacterType()))
+ {
+ break;
+ }
+ }
+ if (loplugin::TypeCheck(d->getParamDecl(1)->getType())
+ .Struct("Dummy")
+ .Namespace("libreoffice_internal")
+ .Namespace("rtl")
+ .GlobalNamespace())
+ {
+ break;
+ }
+ return;
+ }
+ default:
+ return;
}
report(DiagnosticsEngine::Warning,
- "instead of an empty %0, pass an empty '%select{std::string_view|std::u16string_view}1'",
+ "instead of an %0, pass a '%select{std::string_view|std::u16string_view}1'",
expr->getExprLoc())
<< expr->getType()
<< (loplugin::TypeCheck(expr->getType()).Class("OString").Namespace("rtl").GlobalNamespace()