aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2010-05-15 20:07:01 +0100
committerJoseph Myers <jsm28@gcc.gnu.org>2010-05-15 20:07:01 +0100
commit4bdd0a60b27aa25d23cc19e4ab23163edf1a363b (patch)
tree58437182e5b92c32014bc05c7c720abea38f88b9 /gcc
parentd025732d199d5fda6718e4e52661ae027421a5b4 (diff)
downloadgcc-4bdd0a60b27aa25d23cc19e4ab23163edf1a363b.zip
gcc-4bdd0a60b27aa25d23cc19e4ab23163edf1a363b.tar.gz
gcc-4bdd0a60b27aa25d23cc19e4ab23163edf1a363b.tar.bz2
c-decl.c (grokfield): Allow typedefs for anonymous structs and unions by default if...
* 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. 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. From-SVN: r159439
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/c-decl.c33
-rw-r--r--gcc/doc/extend.texi8
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/20080820.c2
-rw-r--r--gcc/testsuite/gcc.dg/anon-struct-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/c1x-anon-struct-1.c73
-rw-r--r--gcc/testsuite/gcc.dg/c1x-anon-struct-2.c57
-rw-r--r--gcc/testsuite/gcc.dg/c90-anon-struct-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/c99-anon-struct-1.c12
10 files changed, 208 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 61d0842..db8e005 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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...
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 03211d6..4bec97f 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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;
}
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7a495eb..d141b14 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1ce44f0..2ee5942 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/gcc.dg/20080820.c b/gcc/testsuite/gcc.dg/20080820.c
index b9dd8a7..002edb1 100644
--- a/gcc/testsuite/gcc.dg/20080820.c
+++ b/gcc/testsuite/gcc.dg/20080820.c
@@ -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" } */
diff --git a/gcc/testsuite/gcc.dg/anon-struct-1.c b/gcc/testsuite/gcc.dg/anon-struct-1.c
index 587d59d..c599fa5 100644
--- a/gcc/testsuite/gcc.dg/anon-struct-1.c
+++ b/gcc/testsuite/gcc.dg/anon-struct-1.c
@@ -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
index 0000000..711fe65
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c1x-anon-struct-1.c
@@ -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
index 0000000..cb804311
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c1x-anon-struct-2.c
@@ -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
index 0000000..a3eb7f7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c90-anon-struct-1.c
@@ -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
index 0000000..87d4c34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-anon-struct-1.c
@@ -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" } */
+};