diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2023-11-08 08:49:28 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2023-11-08 13:44:52 +0100 |
commit | 71d9e8d3e403329428edbda747c7d6bbc705c95f (patch) | |
tree | 824f0143ace32358d06f8785dad9b0fe05e1d6e3 /compilerplugins | |
parent | a9d2b9b7c0c0c9f45f8893ba75f0fff31ef2b4af (diff) |
Adapt loplugin:stringconcatliterals to clang-cl
...whose handling of PredefinedExpr (representing `__func__`) deliberately
differs in IgnoreParens and IgnoreParenImpCasts, see the comment in
StringConcatLiterals::isStringLiteral
Change-Id: I8b001d65369adc3d2a2c47e0cf32578a72ef4eec
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/159111
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/stringconcatliterals.cxx | 26 | ||||
-rw-r--r-- | compilerplugins/clang/test/stringconcatliterals.cxx | 1 |
2 files changed, 21 insertions, 6 deletions
diff --git a/compilerplugins/clang/stringconcatliterals.cxx b/compilerplugins/clang/stringconcatliterals.cxx index 54ca706e208f..9f6482d218f8 100644 --- a/compilerplugins/clang/stringconcatliterals.cxx +++ b/compilerplugins/clang/stringconcatliterals.cxx @@ -78,16 +78,16 @@ bool StringConcatLiterals::VisitCallExpr(CallExpr const * expr) { if ((oo != OverloadedOperatorKind::OO_Plus && oo != OverloadedOperatorKind::OO_LessLess) || fdecl->getNumParams() != 2 || expr->getNumArgs() != 2 - || !isStringLiteral(expr->getArg(1)->IgnoreParenImpCasts())) + || !isStringLiteral(expr->getArg(1))) { return true; } SourceLocation leftLoc; - auto const leftExpr = expr->getArg(0)->IgnoreParenImpCasts(); + auto const leftExpr = expr->getArg(0); if (isStringLiteral(leftExpr)) { - leftLoc = leftExpr->getBeginLoc(); + leftLoc = leftExpr->IgnoreParenImpCasts()->getBeginLoc(); } else { - CallExpr const * left = dyn_cast<CallExpr>(leftExpr); + CallExpr const * left = dyn_cast<CallExpr>(leftExpr->IgnoreParenImpCasts()); if (left == nullptr) { return true; } @@ -99,7 +99,7 @@ bool StringConcatLiterals::VisitCallExpr(CallExpr const * expr) { if ((loo != OverloadedOperatorKind::OO_Plus && loo != OverloadedOperatorKind::OO_LessLess) || ldecl->getNumParams() != 2 || left->getNumArgs() != 2 - || !isStringLiteral(left->getArg(1)->IgnoreParenImpCasts())) + || !isStringLiteral(left->getArg(1))) { return true; } @@ -140,7 +140,21 @@ bool StringConcatLiterals::VisitCallExpr(CallExpr const * expr) { } bool StringConcatLiterals::isStringLiteral(Expr const * expr) { - expr = stripCtor(expr); + // Since <https://github.com/llvm/llvm-project/commit/878e590503dff0d9097e91c2bec4409f14503b82> + // "Reland [clang] Make predefined expressions string literals under -fms-extensions", in MS + // compatibility mode only, IgnoreParens and IgnoreParenImpCasts look through a PredefinedExpr + // representing __func__, but which we do not want to do here: + while (auto const e = dyn_cast<ParenExpr>(expr)) { + expr = e->getSubExpr(); + } + expr = expr->IgnoreImpCasts(); + if (isa<PredefinedExpr>(expr)) { + return false; + } + // Once we have filtered out the problematic PredefinedExpr above, still call + // IgnoreParenImpCasts again, because it does more than just ignore ParenExpr and call + // IgnoreImpCasts as is done above: + expr = stripCtor(expr->IgnoreParenImpCasts()); if (!isa<clang::StringLiteral>(expr)) { return false; } diff --git a/compilerplugins/clang/test/stringconcatliterals.cxx b/compilerplugins/clang/test/stringconcatliterals.cxx index 8b390f28fbbb..0575eb252bc0 100644 --- a/compilerplugins/clang/test/stringconcatliterals.cxx +++ b/compilerplugins/clang/test/stringconcatliterals.cxx @@ -40,6 +40,7 @@ void f(std::ostream& s1) s1 << "foo" << OUString(FOO); // expected-error@-1 {{replace '<<' between string literals with juxtaposition}} s1 << "foo" << OUString(foo); + s1 << "foo" << __func__; OString s2; s2 = "foo" + OString("foo"); // expected-error@-1 {{replace '+' between string literals with juxtaposition}} |