summaryrefslogtreecommitdiff
path: root/compilerplugins
diff options
context:
space:
mode:
authorStephan Bergmann <stephan.bergmann@allotropia.de>2023-11-27 21:43:55 +0100
committerStephan Bergmann <stephan.bergmann@allotropia.de>2023-11-30 14:35:13 +0100
commitf824c4f23c01510b12b53f33778bfa72f7a2ea57 (patch)
tree63027431742c5722162fb38087d156c4d4e5f2a0 /compilerplugins
parent266a0e72e8382f0b72fa7b1127ce8712103aa562 (diff)
Extended loplugin:ostr
Change-Id: I987d6d60ca2d1e8ed8b8cde1e0c7996c0fff71b9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160006 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Diffstat (limited to 'compilerplugins')
-rw-r--r--compilerplugins/clang/ostr.cxx83
-rw-r--r--compilerplugins/clang/test/ostr.cxx10
2 files changed, 91 insertions, 2 deletions
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" };