This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] limit and document unnamed fields.
> I shouldn't have thought it would be more than a few lines of code (a
> couple of recursive functions) to make these recursive checks.
I agree, but that's still more difficult than just documenting that
it's undefined ;-) I figure it would involve one recursive function
and some sort of hash to keep track of what field names we've seen in
the current "scope".
> OK, send the revised patch that keeps the test in grokfield but makes the
> documentation say the case of duplicate names is undefined and I'll review
> it.
2001-10-03 DJ Delorie <dj@redhat.com>
* c-decl.c (grokfield): Make sure the only unnamed fields
we're allowing are either structs or unions.
* doc/extend.texi: Add documentation for the unnamed field
extension.
* gcc.dg/20011008-1.c: New.
* gcc.dg/20011008-2.c: New.
Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.250
diff -p -3 -r1.250 c-decl.c
*** c-decl.c 2001/10/07 18:02:43 1.250
--- c-decl.c 2001/10/08 18:39:55
*************** grokfield (filename, line, declarator, d
*** 5366,5371 ****
--- 5366,5383 ----
{
tree value;
+ if (declarator == NULL_TREE && width == NULL_TREE)
+ {
+ /* This is an unnamed decl. We only support unnamed
+ structs/unions, so check for other things and refuse them. */
+ if (TREE_CODE (TREE_VALUE (declspecs)) != RECORD_TYPE
+ && TREE_CODE (TREE_VALUE (declspecs)) != UNION_TYPE)
+ {
+ error ("unnamed fields of type other than struct or union are not allowed");
+ return NULL_TREE;
+ }
+ }
+
value = grokdeclarator (declarator, declspecs, width ? BITFIELD : FIELD, 0);
finish_decl (value, NULL_TREE, NULL_TREE);
Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.27
diff -p -3 -r1.27 extend.texi
*** extend.texi 2001/10/02 23:15:55 1.27
--- extend.texi 2001/10/08 18:40:40
*************** extensions, accepted by GCC in C89 mode
*** 433,438 ****
--- 433,439 ----
* Vector Extensions:: Using vector instructions through built-in functions.
* Other Builtins:: Other built-in functions.
* Pragmas:: Pragmas accepted by GCC.
+ * Unnamed Fields:: Unnamed struct/union fields within structs/unions.
@end menu
@end ifset
@ifclear INTERNALS
*************** produce warnings for the listed variable
*** 4502,4507 ****
--- 4503,4549 ----
that of the @code{unused} attribute, except that this pragma may appear
anywhere within the variables' scopes.
@end table
+
+ @node Unnamed Fields
+ @section Unnamed struct/union fields within structs/unions.
+ @cindex struct
+ @cindex union
+
+ 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:
+
+ @example
+ struct @{
+ int a;
+ union @{
+ int b;
+ float c;
+ @};
+ int d;
+ @} foo;
+ @end example
+
+ In this example, the user would be able to access members of the unnamed
+ union with code like @samp{foo.b}. Note that only unnamed structs and
+ unions are allowed, you may not have, for example, an unnamed
+ @code{int}.
+
+ You must never create such structures that cause ambiguous field definitions.
+ For example, this structure:
+
+ @example
+ struct @{
+ int a;
+ struct @{
+ int a;
+ @};
+ @} foo;
+ @end example
+
+ It is ambiguous which @code{a} is being referred to with @samp{foo.a}.
+ Such constructs are not supported and must be avoided. In the future,
+ such constructs may be detected and treated as compilation errors.
@node C++ Extensions
@chapter Extensions to the C++ Language
----------------------------------------
/* { dg-do compile } */
/* { dg-options "-O0" } */
struct { int; int q; } a; /* { dg-error "Unnamed" } */
struct { union {int x;}; int q; } b;
struct { struct {int x;}; int q; } c;
union { union {int x;}; int q; } d;
union { struct {int x;}; int q; } e;
----------------------------------------
/* { dg-do run } */
/* { dg-options "-O0" } */
struct { union {int x; int y;}; int q; } b;
union { struct {int x;}; int q; } e;
main()
{
b.y = 10;
b.x = 15;
if (b.y != 15)
abort();
e.x = 10;
e.q = 15;
if (e.x != 15)
abort();
exit(0);
}