OSDN Git Service

* c-decl.c (grokfield): Allow typedefs for anonymous structs and
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 May 2010 19:07:01 +0000 (19:07 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 May 2010 19:07:01 +0000 (19:07 +0000)
unions by default if those structs and unions have no tags.  Do
not condition anonymous struct and unions handling on flag_iso.
Allow anonymous structs and unions for C1X.
(finish_struct): Do not diagnose lack of named fields when
anonymous structs and unions present for C1X.  Accept flexible
array members in structure with anonymous structs or unions but no
directly named fields.
* doc/extend.texi (Unnamed Fields): Update.

testsuite:
* gcc.dg/c1x-anon-struct-1.c, gcc.dg/c1x-anon-struct-2.c,
gcc.dg/c90-anon-struct-1.c, gcc.dg/c99-anon-struct-1.c: New tests.
* gcc.dg/20080820.c, gcc.dg/anon-struct-1.c: Update expected
diagnostics and type sizes.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159439 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-decl.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20080820.c
gcc/testsuite/gcc.dg/anon-struct-1.c
gcc/testsuite/gcc.dg/c1x-anon-struct-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c1x-anon-struct-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c90-anon-struct-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c99-anon-struct-1.c [new file with mode: 0644]

index 61d0842..db8e005 100644 (file)
@@ -1,3 +1,15 @@
+2010-05-15  Joseph Myers  <joseph@codesourcery.com>
+
+       * c-decl.c (grokfield): Allow typedefs for anonymous structs and
+       unions by default if those structs and unions have no tags.  Do
+       not condition anonymous struct and unions handling on flag_iso.
+       Allow anonymous structs and unions for C1X.
+       (finish_struct): Do not diagnose lack of named fields when
+       anonymous structs and unions present for C1X.  Accept flexible
+       array members in structure with anonymous structs or unions but no
+       directly named fields.
+       * doc/extend.texi (Unnamed Fields): Update.
+
 2010-05-15  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gimple.h (compare_field_offset): Rename into...
index 03211d6..4bec97f 100644 (file)
@@ -6567,6 +6567,8 @@ grokfield (location_t loc,
           Otherwise this is a forward declaration of a structure tag.
 
         If this is something of the form "foo;" and foo is a TYPE_DECL, then
+          If foo names a structure or union without a tag, then this
+            is an anonymous struct (this is permitted by C1X).
           If MS extensions are enabled and foo names a structure, then
             again this is an anonymous struct.
           Otherwise this is an error.
@@ -6580,14 +6582,11 @@ grokfield (location_t loc,
                      || TREE_CODE (type) == UNION_TYPE);
       bool ok = false;
 
-      if (type_ok
-         && (flag_ms_extensions || !declspecs->typedef_p))
+      if (type_ok)
        {
          if (flag_ms_extensions)
            ok = true;
-         else if (flag_iso)
-           ok = false;
-         else if (TYPE_NAME (type) == NULL)
+         else if (TYPE_NAME (TYPE_MAIN_VARIANT (type)) == NULL)
            ok = true;
          else
            ok = false;
@@ -6597,7 +6596,15 @@ grokfield (location_t loc,
          pedwarn (loc, 0, "declaration does not declare anything");
          return NULL_TREE;
        }
-      pedwarn (loc, OPT_pedantic, "ISO C doesn%'t support unnamed structs/unions");
+      if (!flag_isoc1x)
+       {
+         if (flag_isoc99)
+           pedwarn (loc, OPT_pedantic,
+                    "ISO C99 doesn%'t support unnamed structs/unions");
+         else
+           pedwarn (loc, OPT_pedantic,
+                    "ISO C90 doesn%'t support unnamed structs/unions");
+       }
     }
 
   value = grokdeclarator (declarator, declspecs, FIELD, false,
@@ -6789,8 +6796,14 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
   if (pedantic)
     {
       for (x = fieldlist; x; x = TREE_CHAIN (x))
-       if (DECL_NAME (x) != 0)
-         break;
+       {
+         if (DECL_NAME (x) != 0)
+           break;
+         if (flag_isoc1x
+             && (TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+                 || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE))
+           break;
+       }
 
       if (x == 0)
        {
@@ -6893,7 +6906,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
        pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic,
                 "invalid use of structure with flexible array member");
 
-      if (DECL_NAME (x))
+      if (DECL_NAME (x)
+         || TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+         || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
        saw_named_field = 1;
     }
 
index 7a495eb..d141b14 100644 (file)
@@ -12727,7 +12727,8 @@ versions earlier than 4.4.
 @cindex struct
 @cindex union
 
-For compatibility with other compilers, GCC allows you to define
+As permitted by ISO C1X and for compatibility with other compilers,
+GCC allows you to define
 a structure or union that contains, as fields, structures and unions
 without names.  For example:
 
@@ -12765,11 +12766,12 @@ The compiler gives errors for such constructs.
 @opindex fms-extensions
 Unless @option{-fms-extensions} is used, the unnamed field must be a
 structure or union definition without a tag (for example, @samp{struct
-@{ int a; @};}).  If @option{-fms-extensions} is used, the field may
+@{ int a; @};}), or a @code{typedef} name for such a structure or
+union.  If @option{-fms-extensions} is used, the field may
 also be a definition with a tag such as @samp{struct foo @{ int a;
 @};}, a reference to a previously defined structure or union such as
 @samp{struct foo;}, or a reference to a @code{typedef} name for a
-previously defined structure or union type.
+previously defined structure or union type with a tag.
 
 @node Thread-Local
 @section Thread-Local Storage
index 1ce44f0..2ee5942 100644 (file)
@@ -1,3 +1,10 @@
+2010-05-15  Joseph Myers  <joseph@codesourcery.com>
+
+       * gcc.dg/c1x-anon-struct-1.c, gcc.dg/c1x-anon-struct-2.c,
+       gcc.dg/c90-anon-struct-1.c, gcc.dg/c99-anon-struct-1.c: New tests.
+       * gcc.dg/20080820.c, gcc.dg/anon-struct-1.c: Update expected
+       diagnostics and type sizes.
+
 2010-05-15  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/lto9.adb: New test.
index b9dd8a7..002edb1 100644 (file)
@@ -1,4 +1,4 @@
 /* { dg-do compile } */
 /* { dg-options "-fshow-column -fms-extensions -pedantic" } */
 
-struct { struct a { int x; }; int bar; } hot; /* { dg-warning "29:ISO C doesn't support unnamed" } */
+struct { struct a { int x; }; int bar; } hot; /* { dg-warning "29:ISO C90 doesn't support unnamed" } */
index 587d59d..c599fa5 100644 (file)
@@ -1,4 +1,4 @@
-/* { dg-options "-std=iso9899:1990" } */
+/* { dg-options "-std=iso9899:1990 -pedantic" } */
 /* In strict ISO C mode, we don't recognize the anonymous struct/union
    extension or any Microsoft extensions.  */
 
@@ -21,10 +21,10 @@ char testD[sizeof(struct D) == sizeof(struct A) ? 1 : -1];
 
 /* GNU extension.  */
 struct E {
-  struct { char z; };          /* { dg-warning "does not declare anything" } */
+  struct { char z; };          /* { dg-warning "unnamed structs" } */
   char e;
 };
-char testE[sizeof(struct E) == sizeof(struct A) ? 1 : -1];
+
 
 /* MS extension.  */
 typedef struct A typedef_A;
@@ -49,8 +49,8 @@ char testH[sizeof(struct H) == 2 * sizeof(struct A) ? 1 : -1];
 
 /* Make sure __extension__ gets turned back off.  */
 struct I {
-  struct { char z; };          /* { dg-warning "does not declare anything" } */
+  struct { char z; };          /* { dg-warning "unnamed structs" } */
   char i;
 };
-char testI[sizeof(struct I) == sizeof(struct A) ? 1 : -1];
+char testI[sizeof(struct I) == sizeof(struct E) ? 1 : -1];
 
diff --git a/gcc/testsuite/gcc.dg/c1x-anon-struct-1.c b/gcc/testsuite/gcc.dg/c1x-anon-struct-1.c
new file mode 100644 (file)
index 0000000..711fe65
--- /dev/null
@@ -0,0 +1,73 @@
+/* Test for anonymous structures and unions in C1X.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+#include <stddef.h>
+
+typedef struct
+{
+  int i;
+} s0;
+
+typedef union
+{
+  int i;
+} u0;
+
+struct s1
+{
+  int a;
+  u0;
+  struct
+  {
+    int b;
+  };
+};
+
+union u1
+{
+  int b;
+  s0;
+  union
+  {
+    int c;
+  };
+};
+
+struct s2
+{
+  struct
+  {
+    int a;
+  };
+};
+
+struct s3
+{
+  u0;
+};
+
+struct s4
+{
+  struct
+  {
+    int i;
+  };
+  int a[];
+};
+
+struct s1 x =
+  {
+    .b = 1,
+    .i = 2,
+    .a = 3
+  };
+
+int o = offsetof (struct s1, i);
+
+void
+f (void)
+{
+  x.i = 3;
+  (&x)->i = 4;
+}
diff --git a/gcc/testsuite/gcc.dg/c1x-anon-struct-2.c b/gcc/testsuite/gcc.dg/c1x-anon-struct-2.c
new file mode 100644 (file)
index 0000000..cb80431
--- /dev/null
@@ -0,0 +1,57 @@
+/* Test for anonymous structures and unions in C1X.  Test for invalid
+   cases.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c1x -pedantic-errors" } */
+
+typedef struct s0
+{
+  int i;
+} s0;
+
+struct s1
+{
+  int a;
+  struct s0; /* { dg-error "declaration does not declare anything" } */
+};
+
+struct s2
+{
+  int a;
+  s0; /* { dg-error "declaration does not declare anything" } */
+};
+
+struct s3
+{
+  struct
+  {
+    int i;
+  };
+  struct
+  {
+    int i; /* { dg-error "duplicate member" } */
+  };
+};
+
+struct s4
+{
+  int a;
+  struct s
+  {
+    int i;
+  }; /* { dg-error "declaration does not declare anything" } */
+};
+
+struct s5
+{
+  struct
+  {
+    int i;
+  } a;
+  int b;
+} x;
+
+void
+f (void)
+{
+  x.i = 0; /* { dg-error "has no member" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c90-anon-struct-1.c b/gcc/testsuite/gcc.dg/c90-anon-struct-1.c
new file mode 100644 (file)
index 0000000..a3eb7f7
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test for anonymous structures and unions not permitted in C90.  */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
+
+struct s
+{
+  int a;
+  struct
+  {
+    int b;
+  }; /* { dg-error "unnamed structs" } */
+};
diff --git a/gcc/testsuite/gcc.dg/c99-anon-struct-1.c b/gcc/testsuite/gcc.dg/c99-anon-struct-1.c
new file mode 100644 (file)
index 0000000..87d4c34
--- /dev/null
@@ -0,0 +1,12 @@
+/* Test for anonymous structures and unions not permitted in C99.  */
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+struct s
+{
+  int a;
+  struct
+  {
+    int b;
+  }; /* { dg-error "unnamed structs" } */
+};