compilerplugins/clang/stringconcatliterals.cxx      |   26 +++++++++++++++-----
 compilerplugins/clang/test/stringconcatliterals.cxx |    1 
 2 files changed, 21 insertions(+), 6 deletions(-)

New commits:
commit 71d9e8d3e403329428edbda747c7d6bbc705c95f
Author:     Stephan Bergmann <sberg...@redhat.com>
AuthorDate: Wed Nov 8 08:49:28 2023 +0100
Commit:     Stephan Bergmann <sberg...@redhat.com>
CommitDate: Wed Nov 8 13:44:52 2023 +0100

    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 <sberg...@redhat.com>

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}}

Reply via email to