diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2023-07-21 22:42:35 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2023-07-31 23:24:52 +0200 |
commit | 5d80385fd167e5e88bb0ce959c78568d7d817842 (patch) | |
tree | bd71c541fc226f1b8a6986ba45148762f9e079ca /compilerplugins/clang/stringconstant.cxx | |
parent | f0b8ad888aff453e1a765611dceb6bc1cf970780 (diff) |
loplugin:stringconstant: Catch some O[U]String::getStr anti-patterns
Change-Id: I36bc86fcffc3c10fe44e60d779c9aa48eeed00f2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154749
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins/clang/stringconstant.cxx')
-rw-r--r-- | compilerplugins/clang/stringconstant.cxx | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/compilerplugins/clang/stringconstant.cxx b/compilerplugins/clang/stringconstant.cxx index cf1eb6afedbf..c64c2c9d6589 100644 --- a/compilerplugins/clang/stringconstant.cxx +++ b/compilerplugins/clang/stringconstant.cxx @@ -191,6 +191,8 @@ public: bool VisitCallExpr(CallExpr const * expr); + bool VisitCXXMemberCallExpr(CXXMemberCallExpr const * expr); + bool VisitCXXConstructExpr(CXXConstructExpr const * expr); bool VisitReturnStmt(ReturnStmt const * stmt); @@ -856,6 +858,47 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) { return true; } +bool StringConstant::VisitCXXMemberCallExpr(CXXMemberCallExpr const * expr) { + if (ignoreLocation(expr)) { + return true; + } + FunctionDecl const * fdecl = expr->getDirectCallee(); + if (fdecl == nullptr) { + return true; + } + auto const c = loplugin::DeclCheck(fdecl).Function("getStr"); + if ((c.Class("OString").Namespace("rtl").GlobalNamespace() + || c.Class("OUString").Namespace("rtl").GlobalNamespace()) + && fdecl->getNumParams() == 0) + { + auto const e1 = expr->getImplicitObjectArgument()->IgnoreImplicit()->IgnoreParens(); + if (auto const e2 = dyn_cast<CXXTemporaryObjectExpr>(e1)) { + if (e2->getNumArgs() != 0) { + return true; + } + report( + DiagnosticsEngine::Warning, + "in call of '%0', replace default-constructed %1 directly with an empty %select{ordinary|UTF-16}2 string literal", + expr->getExprLoc()) + << fdecl->getQualifiedNameAsString() << e2->getType() << bool(loplugin::TypeCheck(e2->getType()).Class("OUString")) << expr->getSourceRange(); + return true; + } + if (auto const e2 = dyn_cast<CXXFunctionalCastExpr>(e1)) { + auto const e3 = dyn_cast<clang::StringLiteral>(e2->getSubExprAsWritten()->IgnoreParens()); + if (e3 == nullptr) { + return true; + } + report( + DiagnosticsEngine::Warning, + "in call of '%0', replace %1 constructed from a string literal directly with %select{the|a UTF-16}2 string literal", + expr->getExprLoc()) + << fdecl->getQualifiedNameAsString() << e2->getType() << (loplugin::TypeCheck(e2->getType()).Class("OUString") && !e3->isUTF16()) << expr->getSourceRange(); + return true; + } + } + return true; +} + bool StringConstant::VisitCXXConstructExpr(CXXConstructExpr const * expr) { if (ignoreLocation(expr)) { return true; |