Commit 4bdd0a60 by Joseph Myers Committed by Joseph Myers

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
parent d025732d
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> 2010-05-15 Eric Botcazou <ebotcazou@adacore.com>
* gimple.h (compare_field_offset): Rename into... * gimple.h (compare_field_offset): Rename into...
......
...@@ -6567,6 +6567,8 @@ grokfield (location_t loc, ...@@ -6567,6 +6567,8 @@ grokfield (location_t loc,
Otherwise this is a forward declaration of a structure tag. 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 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 If MS extensions are enabled and foo names a structure, then
again this is an anonymous struct. again this is an anonymous struct.
Otherwise this is an error. Otherwise this is an error.
...@@ -6580,14 +6582,11 @@ grokfield (location_t loc, ...@@ -6580,14 +6582,11 @@ grokfield (location_t loc,
|| TREE_CODE (type) == UNION_TYPE); || TREE_CODE (type) == UNION_TYPE);
bool ok = false; bool ok = false;
if (type_ok if (type_ok)
&& (flag_ms_extensions || !declspecs->typedef_p))
{ {
if (flag_ms_extensions) if (flag_ms_extensions)
ok = true; ok = true;
else if (flag_iso) else if (TYPE_NAME (TYPE_MAIN_VARIANT (type)) == NULL)
ok = false;
else if (TYPE_NAME (type) == NULL)
ok = true; ok = true;
else else
ok = false; ok = false;
...@@ -6597,7 +6596,15 @@ grokfield (location_t loc, ...@@ -6597,7 +6596,15 @@ grokfield (location_t loc,
pedwarn (loc, 0, "declaration does not declare anything"); pedwarn (loc, 0, "declaration does not declare anything");
return NULL_TREE; 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, value = grokdeclarator (declarator, declspecs, FIELD, false,
...@@ -6789,8 +6796,14 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, ...@@ -6789,8 +6796,14 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
if (pedantic) if (pedantic)
{ {
for (x = fieldlist; x; x = TREE_CHAIN (x)) 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) if (x == 0)
{ {
...@@ -6893,7 +6906,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, ...@@ -6893,7 +6906,9 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic, pedwarn (DECL_SOURCE_LOCATION (x), OPT_pedantic,
"invalid use of structure with flexible array member"); "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; saw_named_field = 1;
} }
......
...@@ -12727,7 +12727,8 @@ versions earlier than 4.4. ...@@ -12727,7 +12727,8 @@ versions earlier than 4.4.
@cindex struct @cindex struct
@cindex union @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 a structure or union that contains, as fields, structures and unions
without names. For example: without names. For example:
...@@ -12765,11 +12766,12 @@ The compiler gives errors for such constructs. ...@@ -12765,11 +12766,12 @@ The compiler gives errors for such constructs.
@opindex fms-extensions @opindex fms-extensions
Unless @option{-fms-extensions} is used, the unnamed field must be a Unless @option{-fms-extensions} is used, the unnamed field must be a
structure or union definition without a tag (for example, @samp{struct 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; 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 @};}, a reference to a previously defined structure or union such as
@samp{struct foo;}, or a reference to a @code{typedef} name for a @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 @node Thread-Local
@section Thread-Local Storage @section Thread-Local Storage
......
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> 2010-05-15 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/lto9.adb: New test. * gnat.dg/lto9.adb: New test.
......
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-fshow-column -fms-extensions -pedantic" } */ /* { 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" } */
/* { dg-options "-std=iso9899:1990" } */ /* { dg-options "-std=iso9899:1990 -pedantic" } */
/* In strict ISO C mode, we don't recognize the anonymous struct/union /* In strict ISO C mode, we don't recognize the anonymous struct/union
extension or any Microsoft extensions. */ extension or any Microsoft extensions. */
...@@ -21,10 +21,10 @@ char testD[sizeof(struct D) == sizeof(struct A) ? 1 : -1]; ...@@ -21,10 +21,10 @@ char testD[sizeof(struct D) == sizeof(struct A) ? 1 : -1];
/* GNU extension. */ /* GNU extension. */
struct E { struct E {
struct { char z; }; /* { dg-warning "does not declare anything" } */ struct { char z; }; /* { dg-warning "unnamed structs" } */
char e; char e;
}; };
char testE[sizeof(struct E) == sizeof(struct A) ? 1 : -1];
/* MS extension. */ /* MS extension. */
typedef struct A typedef_A; typedef struct A typedef_A;
...@@ -49,8 +49,8 @@ char testH[sizeof(struct H) == 2 * sizeof(struct A) ? 1 : -1]; ...@@ -49,8 +49,8 @@ char testH[sizeof(struct H) == 2 * sizeof(struct A) ? 1 : -1];
/* Make sure __extension__ gets turned back off. */ /* Make sure __extension__ gets turned back off. */
struct I { struct I {
struct { char z; }; /* { dg-warning "does not declare anything" } */ struct { char z; }; /* { dg-warning "unnamed structs" } */
char i; char i;
}; };
char testI[sizeof(struct I) == sizeof(struct A) ? 1 : -1]; char testI[sizeof(struct I) == sizeof(struct E) ? 1 : -1];
/* 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;
}
/* 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" } */
}
/* 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" } */
};
/* 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" } */
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment