mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
d025732d19
commit
4bdd0a60b2
|
@ -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>
|
2010-05-15 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* gimple.h (compare_field_offset): Rename into...
|
* gimple.h (compare_field_offset): Rename into...
|
||||||
|
|
29
gcc/c-decl.c
29
gcc/c-decl.c
|
@ -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,
|
||||||
|| 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,
|
||||||
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,
|
||||||
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)
|
if (DECL_NAME (x) != 0)
|
||||||
break;
|
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,
|
||||||
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.
|
||||||
@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.
|
||||||
@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
|
||||||
|
|
|
@ -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>
|
2010-05-15 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* gnat.dg/lto9.adb: New test.
|
* gnat.dg/lto9.adb: New test.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* { 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" } */
|
||||||
|
|
|
@ -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
|
/* 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];
|
||||||
|
|
||||||
/* 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];
|
||||||
|
|
||||||
/* 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];
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -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" } */
|
||||||
|
}
|
|
@ -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" } */
|
||||||
|
};
|
|
@ -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" } */
|
||||||
|
};
|
Loading…
Reference in New Issue