[cfe-commits] r98275 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaInit.cpp test/Sema/missing-field-initializers.c

John McCall rjmccall at apple.com
Thu Mar 11 11:32:38 PST 2010


Author: rjmccall
Date: Thu Mar 11 13:32:38 2010
New Revision: 98275

URL: http://llvm.org/viewvc/llvm-project?rev=98275&view=rev
Log:
Implement -Wmissing-field-initializers.  Patch by mikem!


Added:
    cfe/trunk/test/Sema/missing-field-initializers.c
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaInit.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=98275&r1=98274&r2=98275&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Thu Mar 11 13:32:38 2010
@@ -59,7 +59,7 @@
 def : DiagGroup<"newline-eof">;
 def LongLong : DiagGroup<"long-long">;
 def MismatchedTags : DiagGroup<"mismatched-tags">;
-def : DiagGroup<"missing-field-initializers">;
+def MissingFieldInitializers : DiagGroup<"missing-field-initializers">;
 def NonNull : DiagGroup<"nonnull">;
 def : DiagGroup<"nonportable-cfstrings">;
 def : DiagGroup<"non-virtual-dtor">;
@@ -147,6 +147,7 @@
                         [FormatNonLiteral, FormatSecurity, FormatY2K]>;
 
 def Extra : DiagGroup<"extra", [
+    MissingFieldInitializers,
     SemiBeforeMethodBody,
     SignCompare,
     UnusedParameter

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=98275&r1=98274&r2=98275&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Mar 11 13:32:38 2010
@@ -1562,6 +1562,9 @@
   "excess elements in char array initializer">;
 def warn_initializer_string_for_char_array_too_long : ExtWarn<
   "initializer-string for char array is too long">;
+def warn_missing_field_initializers : Warning<
+  "missing field '%0' initializer">,
+  InGroup<MissingFieldInitializers>, DefaultIgnore;
 def warn_braces_around_scalar_init : Warning<
   "braces around scalar initializer">;
 def err_many_braces_around_scalar_init : Error<

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=98275&r1=98274&r2=98275&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Mar 11 13:32:38 2010
@@ -1051,6 +1051,7 @@
   RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl();
   RecordDecl::field_iterator FieldEnd = RD->field_end();
   bool InitializedSomething = false;
+  bool CheckForMissingFields = true;
   while (Index < IList->getNumInits()) {
     Expr *Init = IList->getInit(Index);
 
@@ -1070,6 +1071,10 @@
         hadError = true;
 
       InitializedSomething = true;
+
+      // Disable check for missing fields when designators are used.
+      // This matches gcc behaviour.
+      CheckForMissingFields = false;
       continue;
     }
 
@@ -1106,6 +1111,21 @@
     ++Field;
   }
 
+  // Emit warnings for missing struct field initializers.
+  if (CheckForMissingFields && Field != FieldEnd && 
+      !Field->getType()->isIncompleteArrayType() && !DeclType->isUnionType()) {
+    // It is possible we have one or more unnamed bitfields remaining.
+    // Find first (if any) named field and emit warning.
+    for (RecordDecl::field_iterator it = Field, end = RD->field_end();
+         it != end; ++it) {
+      if (!it->isUnnamedBitfield()) {
+        SemaRef.Diag(IList->getSourceRange().getEnd(),
+                     diag::warn_missing_field_initializers) << it->getName();
+        break;
+      }
+    }
+  }
+
   if (Field == FieldEnd || !Field->getType()->isIncompleteArrayType() ||
       Index >= IList->getNumInits())
     return;

Added: cfe/trunk/test/Sema/missing-field-initializers.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/missing-field-initializers.c?rev=98275&view=auto
==============================================================================
--- cfe/trunk/test/Sema/missing-field-initializers.c (added)
+++ cfe/trunk/test/Sema/missing-field-initializers.c Thu Mar 11 13:32:38 2010
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-field-initializers %s
+
+struct Foo { int a, b; };
+
+struct Foo foo0 = { 1 }; // expected-warning {{missing field 'b' initializer}}
+struct Foo foo1 = { .a = 1 }; // designator avoids MFI warning
+struct Foo foo2 = { .b = 1 }; // designator avoids MFI warning
+
+struct Foo bar0[] = {
+  { 1,2 },
+  { 1 },   // expected-warning {{missing field 'b' initializer}}
+  { 1,2 }
+};
+
+struct Foo bar1[] = {
+  1, 2,
+  1, 2,
+  1
+}; // expected-warning {{missing field 'b' initializer}}
+
+struct One { int a; int b; };
+struct Two { float c; float d; float e; };
+
+struct Three {
+    union {
+        struct One one;
+        struct Two two;
+    } both;
+};
+
+struct Three t0 = {
+    { .one = { 1, 2 } }
+};
+struct Three t1 = {
+    { .two = { 1.0f, 2.0f, 3.0f } }
+};
+
+struct Three data[] = {
+  { { .one = { 1, 2 } } },
+  { { .one = { 1 } } }, // expected-warning {{missing field 'b' initializer}}
+  { { .two = { 1.0f, 2.0f, 3.0f } } },
+  { { .two = { 1.0f, 2.0f } } } // expected-warning {{missing field 'e' initializer}}
+};
+
+struct { int:5; int a; int:5; int b; int:5 } noNamedImplicit[] = {
+  { 1, 2 },
+  { 1 } // expected-warning {{missing field 'b' initializer}}
+};





More information about the cfe-commits mailing list