diff --git a/compilerplugins/clang/stringadd.cxx b/compilerplugins/clang/stringadd.cxx index 69251411ae70..764ef25adecc 100644 --- a/compilerplugins/clang/stringadd.cxx +++ b/compilerplugins/clang/stringadd.cxx @@ -193,46 +193,30 @@ bool StringAdd::VisitCXXOperatorCallExpr(CXXOperatorCallExpr const* operatorCall && !tc.Class("OString").Namespace("rtl").GlobalNamespace()) return true; - auto check = [/* operatorCall, */ this, &tc](const MaterializeTemporaryExpr* matTempExpr) { - auto tc3 = loplugin::TypeCheck(matTempExpr->getType()); + auto check = [this, &tc](const Expr* expr) { + auto const e = dyn_cast(expr->IgnoreParenImpCasts()); + if (e == nullptr) + return; + auto tc3 = loplugin::TypeCheck(e->getType()); if (!tc3.Class("OUString").Namespace("rtl").GlobalNamespace() && !tc3.Class("OString").Namespace("rtl").GlobalNamespace()) return; - if (auto bindTemp - = dyn_cast(matTempExpr->GetTemporaryExpr()->IgnoreCasts())) - { - // ignore temporaries returned from function calls - if (isa(bindTemp->getSubExpr())) - return; - // we don't have OStringLiteral1, so char needs to generate a temporary - if (tc.Class("OString").Namespace("rtl").GlobalNamespace() - || tc.Struct("OStringConcat").Namespace("rtl").GlobalNamespace()) + // we don't have OStringLiteral1, so char needs to generate a temporary + if (tc.Class("OString").Namespace("rtl").GlobalNamespace() + || tc.Struct("OStringConcat").Namespace("rtl").GlobalNamespace()) + if (auto bindTemp = dyn_cast(e->getSubExpr())) if (auto cxxConstruct = dyn_cast(bindTemp->getSubExpr())) if (loplugin::TypeCheck( cxxConstruct->getConstructor()->getParamDecl(0)->getType()) .Char()) return; - // calls where we pass in an explicit character encoding - if (auto cxxTemp = dyn_cast(bindTemp->getSubExpr())) - if (cxxTemp->getNumArgs() > 1) - return; - } - // conditional operators ( a ? b : c ) will result in temporaries - if (isa( - matTempExpr->GetTemporaryExpr()->IgnoreCasts()->IgnoreParens())) - return; - report(DiagnosticsEngine::Warning, "avoid constructing temporary copies during +", - compat::getBeginLoc(matTempExpr)) - << matTempExpr->getSourceRange(); - // operatorCall->dump(); - // matTempExpr->getType()->dump(); - // operatorCall->getType()->getUnqualifiedDesugaredType()->dump(); + report(DiagnosticsEngine::Warning, "avoid constructing temporary object from %0 during +", + compat::getBeginLoc(e)) + << e->getSubExprAsWritten()->getType() << e->getSourceRange(); }; - if (auto matTempExpr = dyn_cast(operatorCall->getArg(0))) - check(matTempExpr); - if (auto matTempExpr = dyn_cast(operatorCall->getArg(1))) - check(matTempExpr); + check(operatorCall->getArg(0)); + check(operatorCall->getArg(1)); return true; } diff --git a/compilerplugins/clang/test/stringadd.cxx b/compilerplugins/clang/test/stringadd.cxx index 0e0986258254..fc06e5e33b5c 100644 --- a/compilerplugins/clang/test/stringadd.cxx +++ b/compilerplugins/clang/test/stringadd.cxx @@ -163,9 +163,9 @@ void f1(OUString s, OUString t, int i, const char* pChar) { // no warning expected t = t + "xxx"; - // expected-error@+1 {{avoid constructing temporary copies during + [loplugin:stringadd]}} + // expected-error@+1 {{avoid constructing temporary object from 'const char [4]' during + [loplugin:stringadd]}} s = s + OUString("xxx"); - // expected-error@+1 {{avoid constructing temporary copies during + [loplugin:stringadd]}} + // expected-error@+1 {{avoid constructing temporary object from 'const rtl::OUString' during + [loplugin:stringadd]}} s = s + OUString(getByRef()); // no warning expected @@ -183,7 +183,7 @@ void f1(OUString s, OUString t, int i, const char* pChar) void f2(char ch) { OString s; - // expected-error@+1 {{avoid constructing temporary copies during + [loplugin:stringadd]}} + // expected-error@+1 {{avoid constructing temporary object from 'const char [4]' during + [loplugin:stringadd]}} s = s + OString("xxx"); // no warning expected, no OStringLiteral1 s = s + OString(ch);