[Diagnostics] Reworked -Wstring-concatenation
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 77e15f1..fee748b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12886,6 +12886,53 @@
                                                AttributeCommonInfo::AS_Pragma));
   }
 
+  if (var->hasInit() && isa<InitListExpr>(var->getInit())) {
+    const auto *ILE = cast<InitListExpr>(var->getInit());
+    unsigned NumInits = ILE->getNumInits();
+    if (NumInits > 2)
+      for (unsigned I = 0; I < NumInits; ++I) {
+        const auto *Init = ILE->getInit(I);
+        if (!Init)
+          break;
+        const auto *SL = dyn_cast<StringLiteral>(Init->IgnoreImpCasts());
+        if (!SL)
+          break;
+
+        unsigned NumConcat = SL->getNumConcatenated();
+        // Diagnose missing comma in string array initialization.
+        // Do not warn when all the elements in the initializer are concatenated
+        // together. Do not warn for macros too.
+        if (NumConcat == 2 && !SL->getBeginLoc().isMacroID()) {
+          bool OnlyOneMissingComma = true;
+          for (unsigned J = I + 1; J < NumInits; ++J) {
+            const auto *Init = ILE->getInit(J);
+            if (!Init)
+              break;
+            const auto *SLJ = dyn_cast<StringLiteral>(Init->IgnoreImpCasts());
+            if (!SLJ || SLJ->getNumConcatenated() > 1) {
+              OnlyOneMissingComma = false;
+              break;
+            }
+          }
+
+          if (OnlyOneMissingComma) {
+            SmallVector<FixItHint, 1> Hints;
+            for (unsigned i = 0; i < NumConcat - 1; ++i)
+              Hints.push_back(FixItHint::CreateInsertion(
+                  PP.getLocForEndOfToken(SL->getStrTokenLoc(i)), ","));
+
+            Diag(SL->getStrTokenLoc(1),
+                 diag::warn_concatenated_literal_array_init)
+                << Hints;
+            Diag(SL->getBeginLoc(),
+                 diag::note_concatenated_string_literal_silence);
+          }
+          // Warn just once.
+          break;
+        }
+      }
+  }
+
   // All the following checks are C++ only.
   if (!getLangOpts().CPlusPlus) {
       // If this variable must be emitted, add it as an initializer for the
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index bea693f..5e9fca1 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6870,7 +6870,6 @@
   bool DiagnosedArrayDesignator = false;
   bool DiagnosedNestedDesignator = false;
   bool DiagnosedMixedDesignator = false;
-  bool DiagnosedMissingComma = false;
 
   // Check that any designated initializers are syntactically valid in the
   // current language mode.
@@ -6912,37 +6911,6 @@
         << DIE->getSourceRange();
       Diag(InitArgList[I]->getBeginLoc(), diag::note_designated_init_mixed)
         << InitArgList[I]->getSourceRange();
-    } else if (const auto *SL = dyn_cast<StringLiteral>(InitArgList[I])) {
-      unsigned NumConcat = SL->getNumConcatenated();
-      // Diagnose missing comma in string array initialization.
-      // Do not warn when all the elements in the initializer are concatenated
-      // together. Do not warn for macros too.
-      if (!DiagnosedMissingComma && NumConcat == 2 && E > 2 && !SL->getBeginLoc().isMacroID()) {
-        bool OnlyOneMissingComma = true;
-        for (unsigned J = 0; J < E; ++J) {
-          if (J == I)
-            continue;
-          const auto *SLJ = dyn_cast<StringLiteral>(InitArgList[J]);
-          if (!SLJ || SLJ->getNumConcatenated() > 1) {
-            OnlyOneMissingComma = false;
-            break;
-          }
-        }
-
-        if (OnlyOneMissingComma) {
-          SmallVector<FixItHint, 1> Hints;
-          for (unsigned i = 0; i < NumConcat - 1; ++i)
-            Hints.push_back(FixItHint::CreateInsertion(
-                PP.getLocForEndOfToken(SL->getStrTokenLoc(i)), ","));
-
-          Diag(SL->getStrTokenLoc(1),
-               diag::warn_concatenated_literal_array_init)
-              << Hints;
-          Diag(SL->getBeginLoc(),
-               diag::note_concatenated_string_literal_silence);
-          DiagnosedMissingComma = true;
-        }
-      }
     }
   }
 
diff --git a/clang/test/Sema/string-concat.c b/clang/test/Sema/string-concat.c
index 3dcde88..b6bae9c 100644
--- a/clang/test/Sema/string-concat.c
+++ b/clang/test/Sema/string-concat.c
@@ -130,6 +130,25 @@
                "url"
 };
 
+typedef struct {
+  const char *a;
+  const char *b;
+  const char *c;
+} A;
+
+const A not_warn5 = (A){"",
+                        ""
+                        "",
+                        ""};
+
+#ifdef __cplusplus
+const A not_warn6 =  A{"",
+                      ""
+                      "",
+                      ""};
+#endif
+
+
 // Do not warn when all the elements in the initializer are concatenated together.
 const char *all_elems_in_init_concatenated[] = {"a" "b" "c"};