diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2015-06-25 12:38:02 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2015-06-25 12:38:40 +0200 |
commit | af333e81037b106702fc4c4d68b0653f80d2fb1b (patch) | |
tree | 521c07b2c2606fe391f0c68e0b5e48ad2c94bb18 /compilerplugins | |
parent | 94c1ea92ce7653f3cf91cfd0efe9546bbdb47ad3 (diff) |
loplugin:stringconstant: Flag more inefficiencies
Change-Id: I47726315f12ef05714bea248d79cc503fb99b23c
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/stringconstant.cxx | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/compilerplugins/clang/stringconstant.cxx b/compilerplugins/clang/stringconstant.cxx index 12bf173bc4f1..9c869218f6cb 100644 --- a/compilerplugins/clang/stringconstant.cxx +++ b/compilerplugins/clang/stringconstant.cxx @@ -98,6 +98,9 @@ private: std::string const & qname, std::string const & replacement, TreatEmpty treatEmpty); + void handleOUStringCtor( + CallExpr const * expr, unsigned arg, std::string const & qname); + std::stack<Expr const *> calls_; }; @@ -292,6 +295,68 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) { TreatEmpty::Error); return true; } + if (qname == "rtl::OUString::reverseCompareTo" + && fdecl->getNumParams() == 1) + { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::equalsIgnoreAsciiCase" + && fdecl->getNumParams() == 1) + { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::match" && fdecl->getNumParams() == 2) { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::matchIgnoreAsciiCase" + && fdecl->getNumParams() == 2) + { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::startsWith" && fdecl->getNumParams() == 2) { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::startsWithIgnoreAsciiCase" + && fdecl->getNumParams() == 2) + { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::endsWith" && fdecl->getNumParams() == 2) { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::endsWithIgnoreAsciiCase" + && fdecl->getNumParams() == 2) + { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::indexOf" && fdecl->getNumParams() == 2) { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::lastIndexOf" && fdecl->getNumParams() == 1) { + handleOUStringCtor(expr, 0, qname); + return true; + } + if (qname == "rtl::OUString::replaceFirst" && fdecl->getNumParams() == 3) { + handleOUStringCtor(expr, 0, qname); + handleOUStringCtor(expr, 1, qname); + return true; + } + if (qname == "rtl::OUString::replaceAll" + && (fdecl->getNumParams() == 2 || fdecl->getNumParams() == 3)) + { + handleOUStringCtor(expr, 0, qname); + handleOUStringCtor(expr, 1, qname); + return true; + } if (qname == "rtl::OUString::equals" && fdecl->getNumParams() == 1) { unsigned n; bool non; @@ -451,6 +516,7 @@ bool StringConstant::VisitCallExpr(CallExpr const * expr) { << expr->getSourceRange(); return true; } + return true; } return true; } @@ -1089,6 +1155,73 @@ void StringConstant::handleCharLen( reportChange(expr, ChangeKind::CharLen, qname, repl, PassThrough::No); } +void StringConstant::handleOUStringCtor( + CallExpr const * expr, unsigned arg, std::string const & qname) +{ + auto e0 = expr->getArg(arg)->IgnoreParenImpCasts(); + auto e1 = dyn_cast<CXXFunctionalCastExpr>(e0); + if (e1 != nullptr) { + e0 = e1->getSubExpr()->IgnoreParenImpCasts(); + } + auto e2 = dyn_cast<CXXBindTemporaryExpr>(e0); + if (e2 == nullptr) { + return; + } + auto e3 = dyn_cast<CXXConstructExpr>( + e2->getSubExpr()->IgnoreParenImpCasts()); + if (e3 == nullptr) { + return; + } + if (e3->getConstructor()->getQualifiedNameAsString() + != "rtl::OUString::OUString") + { + return; + } + if (e3->getNumArgs() == 0) { + report( + DiagnosticsEngine::Warning, + ("in call of %0, replace default-constructed OUString with an empty" + " string literal"), + e3->getExprLoc()) + << qname << expr->getSourceRange(); + return; + } + APSInt res; + if (e3->getNumArgs() == 1 + && e3->getArg(0)->IgnoreParenImpCasts()->isIntegerConstantExpr( + res, compiler.getASTContext())) + { + if (res > 0 && res <= 127) { + report( + DiagnosticsEngine::Warning, + ("in call of %0, replace OUString constructed from a (non-NUL)" + " ASCII char constant with a string literal"), + e3->getExprLoc()) + << qname << expr->getSourceRange(); + } + return; + } + if (e3->getNumArgs() != 2) { + return; + } + unsigned n; + bool non; + bool emb; + bool trm; + if (!isStringConstant( + e3->getArg(0)->IgnoreParenImpCasts(), &n, &non, &emb, &trm)) + { + return; + } + //TODO: non, emb, trm + report( + DiagnosticsEngine::Warning, + ("in call of %0, replace OUString constructed from a string literal" + " directly with the string literal"), + e3->getExprLoc()) + << qname << expr->getSourceRange(); +} + loplugin::Plugin::Registration< StringConstant > X("stringconstant"); } |