]> granicus.if.org Git - clang/commitdiff
g++ is more permissive regarding flexible arrays.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 7 Mar 2011 20:04:04 +0000 (20:04 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 7 Mar 2011 20:04:04 +0000 (20:04 +0000)
It will accept flexible array in union and also as the sole element of a struct/class.

Fixes rdar://9065507.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/SemaCXX/flexible-array-test.cpp

index d7a1c387ac814fe63a7987f4cec6f03974418620..ba439513a49bff47ec1dbb39e9390320868ad8c7 100644 (file)
@@ -2288,12 +2288,17 @@ def ext_flexible_array_in_array : Extension<
   "%0 may not be used as an array element due to flexible array member">;
 def err_flexible_array_init_nonempty : Error<
   "non-empty initialization of flexible array member inside subobject">;
-def ext_flexible_array_empty_aggregate : Extension<
+def ext_flexible_array_empty_aggregate_ms : Extension<
   "flexible array member %0 in otherwise empty %select{struct|class}1 "
   "is a Microsoft extension">, InGroup<Microsoft>;
-def ext_flexible_array_union : Extension<
+def ext_flexible_array_union_ms : Extension<
   "flexible array member %0 in a union is a Microsoft extension">,
   InGroup<Microsoft>;
+def ext_flexible_array_empty_aggregate_gnu : Extension<
+  "flexible array member %0 in otherwise empty %select{struct|class}1 "
+  "is a GNU extension">, InGroup<GNU>;
+def ext_flexible_array_union_gnu : Extension<
+  "flexible array member %0 in a union is a GNU extension">, InGroup<GNU>;
 
 def err_flexible_array_init_needs_braces : Error<
   "flexible array requires brace-enclosed initializer">;
index 0e114eaa864fafb009d4b0c1bfb76cfc13f45002..b6191e82cd25f3ea18603be8c1fe4a8585b6c969 100644 (file)
@@ -7374,20 +7374,27 @@ void Sema::ActOnFields(Scope* S,
       continue;
     } else if (FDTy->isIncompleteArrayType() && Record && 
                ((i == NumFields - 1 && !Record->isUnion()) ||
-                (getLangOptions().Microsoft &&
+                ((getLangOptions().Microsoft || getLangOptions().CPlusPlus) &&
                  (i == NumFields - 1 || Record->isUnion())))) {
       // Flexible array member.
-      // Microsoft is more permissive regarding flexible array.
+      // Microsoft and g++ is more permissive regarding flexible array.
       // It will accept flexible array in union and also
       // as the sole element of a struct/class.
       if (getLangOptions().Microsoft) {
         if (Record->isUnion()) 
-          Diag(FD->getLocation(), diag::ext_flexible_array_union)
+          Diag(FD->getLocation(), diag::ext_flexible_array_union_ms)
             << FD->getDeclName();
         else if (NumFields == 1) 
-          Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate)
+          Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_ms)
             << FD->getDeclName() << Record->getTagKind();
-      } else  if (NumNamedMembers < 1) {
+      } else if (getLangOptions().CPlusPlus) {
+        if (Record->isUnion()) 
+          Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu)
+            << FD->getDeclName();
+        else if (NumFields == 1) 
+          Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_gnu)
+            << FD->getDeclName() << Record->getTagKind();
+      } else if (NumNamedMembers < 1) {
         Diag(FD->getLocation(), diag::err_flexible_array_empty_struct)
           << FD->getDeclName();
         FD->setInvalidDecl();
index 95d8bb1aa4135cca23c74740759fd41e6ff01bed..e6c3132801f805e9b35d261a488404558033e4c2 100644 (file)
@@ -51,5 +51,19 @@ class A {
 
 union B {
   int s;
-  char c[]; // expected-error {{field has incomplete type 'char []'}}
+  char c[];
+};
+
+namespace rdar9065507 {
+
+struct StorageBase {
+  long ref_count;
+  unsigned size;
+  unsigned capacity;
 };
+
+struct Storage : StorageBase {
+  int data[];
+};
+
+}