]> granicus.if.org Git - clang/commitdiff
Allow flexible array initializers that are not surrounded by
authorDouglas Gregor <dgregor@apple.com>
Fri, 20 Mar 2009 00:32:56 +0000 (00:32 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 20 Mar 2009 00:32:56 +0000 (00:32 +0000)
braces. We now build the appropriate fully-structured initializer list
for such things. Per PR3618, verified that we're getting the right
code generation.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67353 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaInit.cpp
test/CodeGen/flexible-array-init.c [new file with mode: 0644]
test/Sema/array-init.c
test/Sema/flexible-array-init.c

index 8b6ef49542d10ad6560771b1e9eab28639e161cb..0518094e4c5d6a2c6c99b4c0143ecad473602598 100644 (file)
@@ -66,6 +66,8 @@ def err_designator_into_flexible_array_member : Error<
   "designator into flexible array member subobject">;
 def note_flexible_array_member : Note<
   "initialized flexible array member %0 is here">;
+def ext_flexible_array_init : Extension<
+  "flexible array initialization is a GNU extension">;
 
 // Declarations.
 def ext_vla : Extension<
index e0d3b7e545d03eb687ef0ae5cf284219aafaf40b..8a5e2c87d34bd78cb8669b09f58c2ca68082126e 100644 (file)
@@ -481,7 +481,8 @@ void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
                         StructuredSubobjectInitIndex,
                         TopLevelObject);
   unsigned EndIndex = (Index == StartIndex? StartIndex : Index - 1);
-  
+  StructuredSubobjectInitList->setType(T);
+
   // Update the structured sub-object initializer so that it's ending
   // range corresponds with the end of the last initializer it used.
   if (EndIndex < ParentIList->getNumInits()) {
@@ -995,23 +996,35 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
   }
 
   if (Field == FieldEnd || !Field->getType()->isIncompleteArrayType() || 
-      Index >= IList->getNumInits() || 
-      !isa<InitListExpr>(IList->getInit(Index)))
+      Index >= IList->getNumInits())
     return;
 
   // Handle GNU flexible array initializers.
   if (!TopLevelObject && 
-      cast<InitListExpr>(IList->getInit(Index))->getNumInits() > 0) {
+      (!isa<InitListExpr>(IList->getInit(Index)) ||
+       cast<InitListExpr>(IList->getInit(Index))->getNumInits() > 0)) {
     SemaRef.Diag(IList->getInit(Index)->getSourceRange().getBegin(), 
                   diag::err_flexible_array_init_nonempty)
       << IList->getInit(Index)->getSourceRange().getBegin();
     SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
       << *Field;
     hadError = true;
+    ++Index;
+    return;
+  } else {
+    SemaRef.Diag(IList->getInit(Index)->getSourceRange().getBegin(), 
+                 diag::ext_flexible_array_init)
+      << IList->getInit(Index)->getSourceRange().getBegin();
+    SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
+      << *Field;
   }
 
-  CheckSubElementType(IList, Field->getType(), Index, StructuredList,
-                      StructuredIndex);
+  if (isa<InitListExpr>(IList->getInit(Index)))
+    CheckSubElementType(IList, Field->getType(), Index, StructuredList,
+                        StructuredIndex);
+  else
+    CheckImplicitInitList(IList, Field->getType(), Index, StructuredList,
+                          StructuredIndex);
 }
 
 /// @brief Check the well-formedness of a C99 designated initializer.
diff --git a/test/CodeGen/flexible-array-init.c b/test/CodeGen/flexible-array-init.c
new file mode 100644 (file)
index 0000000..0e2fcc6
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang -triple i386-unknown-unknown -emit-llvm -o - %s | grep 7 | count 1 &&
+// RUN: clang -triple i386-unknown-unknown -emit-llvm -o - %s | grep 11 | count 1 &&
+// RUN: clang -triple i386-unknown-unknown -emit-llvm -o - %s | grep 13 | count 1 &&
+// RUN: clang -triple i386-unknown-unknown -emit-llvm -o - %s | grep 15 | count 1
+
+struct { int x; int y[]; } a = { 1, 7, 11 };
+
+struct { int x; int y[]; } b = { 1, { 13, 15 } };
index 4ee86181afed890886f64486b848f6c6da003a6e..0c1bbc047094262009f02f2de24928cdd2fda285 100644 (file)
@@ -201,8 +201,8 @@ int bar (void) {
   return z.z; 
 } 
 struct s3 {void (*a)(void);} t5 = {autoStructTest};
-// Note that clang objc implementation depends on this extension.
-struct {int a; int b[];} t6 = {1, {1, 2, 3}};
+struct {int a; int b[];} t6 = {1, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}} \
+// expected-note{{initialized flexible array member 'b' is here}}
 union {char a; int b;} t7[] = {1, 2, 3};
 int t8[sizeof t7 == (3*sizeof(int)) ? 1 : -1];
 
index fff5fee2afc28a3acf41fc75d5ef65f040962947..2b8f40fa5b0f87be1c96950920b52eeed5184030 100644 (file)
@@ -1,24 +1,24 @@
 // RUN: clang -fsyntax-only -pedantic -verify %s
 struct one {
   int a;
-  int values[];
-} x = {5, {1, 2, 3}};
+  int values[]; // expected-note 3{{initialized flexible array member 'values' is here}}
+} x = {5, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}}
 
-struct one x2 = { 5, 1, 2, 3 }; // expected-warning{{excess elements in struct initializer}}
+struct one x2 = { 5, 1, 2, 3 }; // expected-warning{{flexible array initialization is a GNU extension}}
 
 void test() {
-  struct one x3 = {5, {1, 2, 3}};
+  struct one x3 = {5, {1, 2, 3}}; // expected-warning{{flexible array initialization is a GNU extension}}
 }
 
 struct foo { 
   int x; 
-  int y[]; // expected-note 4 {{initialized flexible array member 'y' is here}}
+  int y[]; // expected-note 6 {{initialized flexible array member 'y' is here}}
 }; 
 struct bar { struct foo z; }; // expected-warning {{'z' may not be nested in a struct due to flexible array member}}
      
-struct foo a = { 1, { 2, 3, 4 } };        // Valid.
+struct foo a = { 1, { 2, 3, 4 } };        // expected-warning{{flexible array initialization is a GNU extension}}
 struct bar b = { { 1, { 2, 3, 4 } } };    // expected-error{{non-empty initialization of flexible array member inside subobject}}
-struct bar c = { { 1, { } } };            // Valid. \
+struct bar c = { { 1, { } } };            // // expected-warning{{flexible array initialization is a GNU extension}} \
               // expected-warning{{use of GNU empty initializer extension}} \
               // expected-warning{{zero size arrays are an extension}}
 struct foo d[1] = { { 1, { 2, 3, 4 } } };  // expected-warning{{'struct foo' may not be used as an array element due to flexible array member}} \