[clang] b9af72b - [Diagnostics] Reworked -Wstring-concatenation

Dávid Bolvanský via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 11 17:18:18 PDT 2020


Author: Dávid Bolvanský
Date: 2020-08-12T02:18:01+02:00
New Revision: b9af72bffe5f2769f3a7858a785981f89137a0ce

URL: https://github.com/llvm/llvm-project/commit/b9af72bffe5f2769f3a7858a785981f89137a0ce
DIFF: https://github.com/llvm/llvm-project/commit/b9af72bffe5f2769f3a7858a785981f89137a0ce.diff

LOG: [Diagnostics] Reworked -Wstring-concatenation

Added: 
    

Modified: 
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/test/Sema/string-concat.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 77e15f187e53..fee748bf9f9d 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -12886,6 +12886,53 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
                                                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 bea693f999ab..5e9fca13f1d0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6870,7 +6870,6 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
   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 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList,
         << 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 3dcde8844dff..b6bae9c95b0b 100644
--- a/clang/test/Sema/string-concat.c
+++ b/clang/test/Sema/string-concat.c
@@ -130,6 +130,25 @@ const char *not_warn4[] =  {"title",
                "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"};
 


        


More information about the cfe-commits mailing list