c-parse.in (structsp): Pedwarn when "enum foo" refers to an incomplete type.
* c-parse.in (structsp): Pedwarn when "enum foo" refers to an incomplete type. (typename): Call pending_xref_error after parsing typed_typespecs. * c-decl.c (lookup_tag): Give error immediately rather than leaving it pending if the tag of the wrong type is in the same binding level. (xref_tag): Don't pedwarn for forward declarations of enum types here. * gcc.texi (Actual Bugs): Remove entry for misuse of struct, union and enum tags. testsuite: * gcc.dg/c99-tag-1.c: New test. From-SVN: r39372
This commit is contained in:
parent
92fa350add
commit
0aca1a4fd3
6 changed files with 175 additions and 12 deletions
|
@ -1,3 +1,16 @@
|
|||
2001-01-31 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* c-parse.in (structsp): Pedwarn when "enum foo" refers to an
|
||||
incomplete type.
|
||||
(typename): Call pending_xref_error after parsing typed_typespecs.
|
||||
* c-decl.c (lookup_tag): Give error immediately rather than
|
||||
leaving it pending if the tag of the wrong type is in the same
|
||||
binding level.
|
||||
(xref_tag): Don't pedwarn for forward declarations of enum types
|
||||
here.
|
||||
* gcc.texi (Actual Bugs): Remove entry for misuse of struct, union
|
||||
and enum tags.
|
||||
|
||||
2001-01-31 Alexandre Oliva <aoliva@redhat.com>
|
||||
|
||||
* config/float-sparc.h (LDBL_MAX) [sparc32]: Fix typo.
|
||||
|
|
18
gcc/c-decl.c
18
gcc/c-decl.c
|
@ -2815,6 +2815,7 @@ lookup_tag (code, name, binding_level, thislevel_only)
|
|||
int thislevel_only;
|
||||
{
|
||||
register struct binding_level *level;
|
||||
int thislevel = 1;
|
||||
|
||||
for (level = binding_level; level; level = level->level_chain)
|
||||
{
|
||||
|
@ -2829,12 +2830,22 @@ lookup_tag (code, name, binding_level, thislevel_only)
|
|||
pending_invalid_xref = name;
|
||||
pending_invalid_xref_file = input_filename;
|
||||
pending_invalid_xref_line = lineno;
|
||||
/* If in the same binding level as a declaration as a tag
|
||||
of a different type, this must not be allowed to
|
||||
shadow that tag, so give the error immediately.
|
||||
(For example, "struct foo; union foo;" is invalid.) */
|
||||
if (thislevel)
|
||||
pending_xref_error ();
|
||||
}
|
||||
return TREE_VALUE (tail);
|
||||
}
|
||||
}
|
||||
if (thislevel_only && ! level->tag_transparent)
|
||||
return NULL_TREE;
|
||||
if (! level->tag_transparent)
|
||||
{
|
||||
if (thislevel_only)
|
||||
return NULL_TREE;
|
||||
thislevel = 0;
|
||||
}
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
@ -5112,9 +5123,6 @@ xref_tag (code, name)
|
|||
ref = make_node (code);
|
||||
if (code == ENUMERAL_TYPE)
|
||||
{
|
||||
/* (In ANSI, Enums can be referred to only if already defined.) */
|
||||
if (pedantic)
|
||||
pedwarn ("ISO C forbids forward references to `enum' types");
|
||||
/* Give the type a default layout like unsigned int
|
||||
to avoid crashing if it does not get defined. */
|
||||
TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node);
|
||||
|
|
|
@ -1397,7 +1397,11 @@ structsp:
|
|||
{ $$ = finish_enum ($<ttype>3, nreverse ($4),
|
||||
chainon ($1, $7)); }
|
||||
| enum_head identifier
|
||||
{ $$ = xref_tag (ENUMERAL_TYPE, $2); }
|
||||
{ $$ = xref_tag (ENUMERAL_TYPE, $2);
|
||||
/* In ISO C, enumerated types can be referred to
|
||||
only if already defined. */
|
||||
if (pedantic && !COMPLETE_TYPE_P ($$))
|
||||
pedwarn ("ISO C forbids forward references to `enum' types"); }
|
||||
;
|
||||
|
||||
maybecomma:
|
||||
|
@ -1534,8 +1538,10 @@ enumerator:
|
|||
;
|
||||
|
||||
typename:
|
||||
typed_typespecs absdcl
|
||||
{ $$ = build_tree_list ($1, $2); }
|
||||
typed_typespecs
|
||||
{ pending_xref_error (); }
|
||||
absdcl
|
||||
{ $$ = build_tree_list ($1, $3); }
|
||||
| nonempty_type_quals absdcl
|
||||
{ $$ = build_tree_list ($1, $2); }
|
||||
;
|
||||
|
|
|
@ -536,10 +536,6 @@ The @code{fixproto} script will sometimes add prototypes for the
|
|||
edit the offending file and place the typedef in front of the
|
||||
prototypes.
|
||||
|
||||
@item
|
||||
There are several obscure case of mis-using struct, union, and
|
||||
enum tags that are not detected as errors by the compiler.
|
||||
|
||||
@item
|
||||
When @samp{-pedantic-errors} is specified, GCC will incorrectly give
|
||||
an error message when a function name is specified in an expression
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2001-01-31 Joseph S. Myers <jsm28@cam.ac.uk>
|
||||
|
||||
* gcc.dg/c99-tag-1.c: New test.
|
||||
|
||||
2001-01-31 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* gcc.dg/cpp/tr-warn1.c: Add tests.
|
||||
|
|
136
gcc/testsuite/gcc.dg/c99-tag-1.c
Normal file
136
gcc/testsuite/gcc.dg/c99-tag-1.c
Normal file
|
@ -0,0 +1,136 @@
|
|||
/* Test for handling of tags (6.7.2.3). */
|
||||
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
|
||||
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
/* Forward declarations of structs and unions are OK; those of enums are
|
||||
not. */
|
||||
{
|
||||
struct s0;
|
||||
struct s1 *x0;
|
||||
union u0;
|
||||
union u1 *x1;
|
||||
enum e0; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "forward" "enum forward 1" { target *-*-* } 16 } */
|
||||
enum e1 *x2; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "forward" "enum forward 2" { target *-*-* } 18 } */
|
||||
/* GCC used to fail to diagnose a use of an enum inside its definition. */
|
||||
enum e2 { E2A = sizeof (enum e2 *) }; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "forward" "enum forward 3" { target *-*-* } 21 } */
|
||||
}
|
||||
/* A specific type shall have its content defined at most once. But we
|
||||
may redeclare the tag in different scopes. */
|
||||
{
|
||||
struct s0 { int i; };
|
||||
{
|
||||
struct s0 { long l; };
|
||||
}
|
||||
{
|
||||
union s0 { long l; };
|
||||
}
|
||||
struct s0 { int i; }; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "rede" "struct redef" { target *-*-* } 34 } */
|
||||
union u0 { int i; };
|
||||
{
|
||||
union u0 { long l; };
|
||||
}
|
||||
{
|
||||
struct u0 { long l; };
|
||||
}
|
||||
union u0 { int i; }; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "rede" "union redef" { target *-*-* } 43 } */
|
||||
enum e0 { E0A };
|
||||
{
|
||||
enum e0 { E0B };
|
||||
}
|
||||
{
|
||||
struct e0 { long l; };
|
||||
}
|
||||
enum e0 { E0B }; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "rede" "enum redef" { target *-*-* } 52 } */
|
||||
}
|
||||
/* Structure, union and enumerated types have a single namespace of tags. */
|
||||
{
|
||||
struct s0;
|
||||
struct s1;
|
||||
struct s2 { int i; };
|
||||
struct s2;
|
||||
struct s3 { int i; };
|
||||
struct s2 sv;
|
||||
union u0;
|
||||
union u2 { int i; };
|
||||
union u2;
|
||||
union u2 uv;
|
||||
enum e0 { E0A };
|
||||
enum e1 { E1A };
|
||||
/* None of the following are allowed; some were not detected by GCC. */
|
||||
union s0; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 70 } */
|
||||
union s1 { int i; }; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 72 } */
|
||||
union s2; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 74 } */
|
||||
union s3 { int i; }; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 76 } */
|
||||
enum u0 { U0A }; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 78 } */
|
||||
enum u2 { U2A }; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 80 } */
|
||||
struct e0; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 82 } */
|
||||
struct e1 { int i; }; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 84 } */
|
||||
}
|
||||
/* Explicit shadowing in inner scopes is OK, but references to the tag
|
||||
that don't explicitly shadow it must (whether in declarations or
|
||||
expressions) use the correct one of struct/union/enum. */
|
||||
{
|
||||
struct s0;
|
||||
struct s1;
|
||||
struct s2 { int i; };
|
||||
struct s2;
|
||||
struct s3 { int i; };
|
||||
struct s2 sv;
|
||||
union u0;
|
||||
union u2 { int i; };
|
||||
union u2;
|
||||
union u2 uv;
|
||||
enum e0 { E0A };
|
||||
enum e1 { E1A };
|
||||
{
|
||||
union s0;
|
||||
union s1;
|
||||
union s2;
|
||||
union s3;
|
||||
struct u0;
|
||||
struct u2;
|
||||
struct e0;
|
||||
union e1;
|
||||
}
|
||||
{
|
||||
union s0 *x0; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 114 } */
|
||||
int x1[sizeof (union s1 *)]; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 116 } */
|
||||
struct t;
|
||||
union s2 *x2;
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 119 } */
|
||||
int x3[sizeof (union s3 *)]; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 121 } */
|
||||
struct u;
|
||||
enum u0 *y0; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong|forward" "wrong tag type" { target *-*-* } 124 } */
|
||||
int y1[sizeof (enum u2 *)]; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 126 } */
|
||||
struct v;
|
||||
struct e0 *z0; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 129 } */
|
||||
int z1[sizeof (struct e1 *)]; /* { dg-bogus "warning" "warning in place of error" } */
|
||||
/* { dg-error "wrong" "wrong tag type" { target *-*-* } 131 } */
|
||||
struct w;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue