compilerplugins/clang/ostr.cxx | 83 +++++++++++++++++++++++++++++++++++- compilerplugins/clang/test/ostr.cxx | 10 ++++ sw/qa/extras/layout/layout3.cxx | 9 ++- 3 files changed, 96 insertions(+), 6 deletions(-)
New commits: commit f824c4f23c01510b12b53f33778bfa72f7a2ea57 Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Mon Nov 27 21:43:55 2023 +0100 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Thu Nov 30 14:35:13 2023 +0100 Extended loplugin:ostr Change-Id: I987d6d60ca2d1e8ed8b8cde1e0c7996c0fff71b9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160006 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergm...@allotropia.de> diff --git a/compilerplugins/clang/ostr.cxx b/compilerplugins/clang/ostr.cxx index da68451e6316..189b74da3152 100644 --- a/compilerplugins/clang/ostr.cxx +++ b/compilerplugins/clang/ostr.cxx @@ -352,7 +352,7 @@ public: { return true; } - if (!compiler.getDiagnosticOpts().VerifyDiagnostics) + if (!compiler.getDiagnosticOpts().VerifyDiagnostics && utf16) { //TODO: Leave rewriting these uses of ordinary string literals for later (but already // cover them when verifying CompilerTest_compilerplugins_clang): @@ -364,7 +364,7 @@ public: Lexer::MeasureTokenLength(l3, compiler.getSourceManager(), compiler.getLangOpts())); l4 = l4.getLocWithOffset( Lexer::MeasureTokenLength(l4, compiler.getSourceManager(), compiler.getLangOpts())); - if ((!utf16 || replaceText(l1, delta(l1, l2), macroBegin ? "u\"\" " : "u")) + if (replaceText(l1, delta(l1, l2), utf16 ? (macroBegin ? "u\"\" " : "u") : "") && replaceText(l3, delta(l3, l4), utf16 ? (macroEnd ? " \"\"_ustr" : "_ustr") : (macroEnd ? " \"\"_ostr" : "_ostr"))) @@ -380,6 +380,85 @@ public: return true; } + bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr const* expr) + { + if (ignoreLocation(expr)) + { + return true; + } + if (expr->getOperator() != OO_Equal) + { + return true; + } + if (!loplugin::TypeCheck(expr->getArg(0)->getType()) + .Class("OString") + .Namespace("rtl") + .GlobalNamespace()) + { + return true; + } + auto const e2 = dyn_cast<clang::StringLiteral>(expr->getArg(1)->IgnoreParenImpCasts()); + if (e2 == nullptr) + { + return true; + } + if (rewriter != nullptr) + { + auto loc = e2->getEndLoc(); + auto const macroEnd = loc.isMacroID() + && Lexer::isAtEndOfMacroExpansion( + loc, compiler.getSourceManager(), compiler.getLangOpts()); + if (macroEnd) + { + loc = compiler.getSourceManager().getImmediateMacroCallerLoc(loc); + } + if (insertTextAfterToken(loc, macroEnd ? " \"\"_ostr" : "_ostr")) + { + return true; + } + } + report(DiagnosticsEngine::Warning, + "use a _ostr user-defined string literal instead of assigning from an ordinary" + " string literal", + expr->getExprLoc()) + << expr->getSourceRange(); + return true; + } + + bool VisitCXXMemberCallExpr(CXXMemberCallExpr const* expr) + { + if (ignoreLocation(expr)) + { + return true; + } + if (!loplugin::DeclCheck(expr->getMethodDecl()).Operator(OO_Equal)) + { + return true; + } + if (!loplugin::TypeCheck(expr->getObjectType()) + .Class("OString") + .Namespace("rtl") + .GlobalNamespace()) + { + return true; + } + auto const e2 = dyn_cast<clang::StringLiteral>(expr->getArg(0)->IgnoreParenImpCasts()); + if (e2 == nullptr) + { + return true; + } + if (rewriter != nullptr) + { + //TODO + } + report(DiagnosticsEngine::Warning, + "use a _ostr user-defined string literal instead of assigning from an ordinary" + " string literal", + expr->getExprLoc()) + << expr->getSourceRange(); + return true; + } + bool VisitCastExpr(CastExpr const* expr) { if (ignoreLocation(expr)) diff --git a/compilerplugins/clang/test/ostr.cxx b/compilerplugins/clang/test/ostr.cxx index 8e772b1258a2..e6e3a9b556e2 100644 --- a/compilerplugins/clang/test/ostr.cxx +++ b/compilerplugins/clang/test/ostr.cxx @@ -112,6 +112,16 @@ void f() // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} takeOustring((("foo"))); + OString s9; + // expected-error@+1 {{use a _ostr user-defined string literal instead of assigning from an ordinary string literal [loplugin:ostr]}} + s9 = "foo"; + // expected-error@+1 {{use a _ostr user-defined string literal instead of assigning from an ordinary string literal [loplugin:ostr]}} + s9 = (("foo")); + // expected-error@+1 {{use a _ostr user-defined string literal instead of assigning from an ordinary string literal [loplugin:ostr]}} + s9.operator=("foo"); + // expected-error@+1 {{use a _ostr user-defined string literal instead of assigning from an ordinary string literal [loplugin:ostr]}} + s9.operator=((("foo"))); + // expected-error-re@+1 {{use a _ustr user-defined string literal instead of constructing an instance of '{{(rtl::)?}}OUString' from an ordinary string literal [loplugin:ostr]}} S s10 = { "foo" }; diff --git a/sw/qa/extras/layout/layout3.cxx b/sw/qa/extras/layout/layout3.cxx index f919a6452912..5401cef9a380 100644 --- a/sw/qa/extras/layout/layout3.cxx +++ b/sw/qa/extras/layout/layout3.cxx @@ -216,23 +216,24 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter3, testTdf158333) // shrink line 2 assertXPath( - pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[2]", "portion", + pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[2]"_ostr, "portion"_ostr, "viverra odio. Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. "); // shrink line 7 assertXPath( - pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[7]", "portion", + pXmlDoc, "/root/page/body/txt[1]/SwParaPortion/SwLineLayout[7]"_ostr, "portion"_ostr, // This was "...diam ", not "...diam tempor " "laoreet vel leo nec, volutpat facilisis eros. Donec consequat arcu ut diam tempor "); // shrink line 2 of paragraph 2 assertXPath( - pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[2]", "portion", + pXmlDoc, "/root/page/body/txt[2]/SwParaPortion/SwLineLayout[2]"_ostr, "portion"_ostr, // This was "...Cras ", not "...Cras sodales " "Donec auctor molestie sem, sit amet tristique lectus hendrerit sed. Cras sodales "); // shrink line 2 of paragraph 4 - assertXPath(pXmlDoc, "/root/page/body/txt[4]/SwParaPortion/SwLineLayout[2]", "portion", + assertXPath(pXmlDoc, "/root/page/body/txt[4]/SwParaPortion/SwLineLayout[2]"_ostr, + "portion"_ostr, // This was "...et ", not "...et magnis " "consequat arcu ut diam tempor luctus. Cum sociis natoque penatibus et magnis "); }