diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2020-12-04 16:24:56 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2020-12-04 17:54:48 +0100 |
commit | 6c905fb6430b6ec43630e826f9afd935734f4c91 (patch) | |
tree | 6fefee2c2004bab1afd12bbb6c951a6b427604cb /compilerplugins/clang/stringview.cxx | |
parent | fcb7fe3a082c200f69f10c1d3951761a7e41d6e0 (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.cxx | 74 |
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() |