[cfe-commits] r116647 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/Sema/flexible-array-init.c

Douglas Gregor dgregor at apple.com
Fri Oct 15 16:53:29 PDT 2010


Author: dgregor
Date: Fri Oct 15 18:53:28 2010
New Revision: 116647

URL: http://llvm.org/viewvc/llvm-project?rev=116647&view=rev
Log:
Allow list-initialization of a local variable of class type with a
flexible array member, so long as the flexibility array member is
either not initialized or is initialized with an empty initializer
list. Fixes <rdar://problem/8540437>.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/Sema/flexible-array-init.c

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=116647&r1=116646&r2=116647&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Oct 15 18:53:28 2010
@@ -4395,9 +4395,19 @@
   // global/static definition.
   if (VDecl->hasLocalStorage())
     if (const RecordType *RT = VDecl->getType()->getAs<RecordType>())
-      if (RT->getDecl()->hasFlexibleArrayMember() && isa<InitListExpr>(Init)) {
-        Diag(VDecl->getLocation(), diag::err_nonstatic_flexible_variable);
-        VDecl->setInvalidDecl();
+      if (RT->getDecl()->hasFlexibleArrayMember()) {
+        // Check whether the initializer tries to initialize the flexible
+        // array member itself to anything other than an empty initializer list.
+        if (InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
+          unsigned Index = std::distance(RT->getDecl()->field_begin(),
+                                         RT->getDecl()->field_end()) - 1;
+          if (Index < ILE->getNumInits() &&
+              !(isa<InitListExpr>(ILE->getInit(Index)) &&
+                cast<InitListExpr>(ILE->getInit(Index))->getNumInits() == 0)) {
+            Diag(VDecl->getLocation(), diag::err_nonstatic_flexible_variable);
+            VDecl->setInvalidDecl();
+          }
+        }
       }
   
   // Check any implicit conversions within the expression.

Modified: cfe/trunk/test/Sema/flexible-array-init.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/flexible-array-init.c?rev=116647&r1=116646&r2=116647&view=diff
==============================================================================
--- cfe/trunk/test/Sema/flexible-array-init.c (original)
+++ cfe/trunk/test/Sema/flexible-array-init.c Fri Oct 15 18:53:28 2010
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
 struct one {
   int a;
-  int values[]; // expected-note 3{{initialized flexible array member 'values' is here}}
+  int values[]; // expected-note 4{{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{{flexible array initialization is a GNU extension}}
@@ -10,6 +10,11 @@
   struct one x3 = {5, {1, 2, 3}}; // \
    // expected-warning{{flexible array initialization is a GNU extension}} \
    // expected-error {{non-static initialization of a variable with flexible array member}}
+  struct one x3a = { 5 };
+  struct one x3b = { .a = 5 };
+  struct one x3c = { 5, {} }; // expected-warning{{use of GNU empty initializer extension}} \
+  // expected-warning{{flexible array initialization is a GNU extension}} \
+  // expected-warning{{zero size arrays are an extension}}
 }
 
 struct foo { 
@@ -68,7 +73,7 @@
 
 void PR8217() {
   struct PR8217a foo1 = { .i = 0, .v = "foo" }; // expected-error {{non-static initialization of a variable with flexible array member}}
-  struct PR8217a foo2 = { .i = 0 }; // expected-error {{non-static initialization of a variable with flexible array member}}
+  struct PR8217a foo2 = { .i = 0 };
   struct PR8217a foo3 = { .i = 0, .v = { 'b', 'a', 'r', '\0' } }; // expected-error {{non-static initialization of a variable with flexible array member}}
   struct PR8217a bar;
 }





More information about the cfe-commits mailing list