diff options
| -rw-r--r-- | gcc/ChangeLog | 4 | ||||
| -rw-r--r-- | gcc/c-decl.c | 17 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/c99-tag-1.c | 17 | 
4 files changed, 36 insertions, 6 deletions
| diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ad24ae5..fe8a619 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2001-06-11  Joseph S. Myers  <jsm28@cam.ac.uk> + +	* c-decl.c (xref_tag): Don't return previous tags of wrong type. +  2001-06-11  Aldy Hernandez  <aldyh@redhat.com>          * loop.c (scan_loop): Do not combine asm statements. diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 78c852e..b68f772 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -5226,11 +5226,18 @@ xref_tag (code, name)       already defined for this tag and return it.  */    register tree ref = lookup_tag (code, name, current_binding_level, 0); -  /* Even if this is the wrong type of tag, return what we found. -     There will be an error message anyway, from pending_xref_error. -     If we create an empty xref just for an invalid use of the type, -     the main result is to create lots of superfluous error messages.  */ -  if (ref) +  /* If this is the right type of tag, return what we found. +     (This reference will be shadowed by shadow_tag later if appropriate.) +     If this is the wrong type of tag, do not return it.  If it was the +     wrong type in the same binding level, we will have had an error +     message already; if in a different binding level and declaring +     a name, pending_xref_error will give an error message; but if in a +     different binding level and not declaring a name, this tag should +     shadow the previous declaration of a different type of tag, and +     this would not work properly if we return the reference found. +     (For example, with "struct foo" in an outer scope, "union foo;" +     must shadow that tag with a new one of union type.)  */ +  if (ref && TREE_CODE (ref) == code)      return ref;    /* If no such tag is yet defined, create a forward-reference node diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 467a5e4..d125520 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-06-11  Joseph S. Myers  <jsm28@cam.ac.uk> + +	* gcc.dg/c99-tag-1.c: Add more tests. +  2001-06-10  Alexandre Oliva  <aoliva@redhat.com>  	* g++.old-deja/g++.abi/ptrmem.C: Take into account different diff --git a/gcc/testsuite/gcc.dg/c99-tag-1.c b/gcc/testsuite/gcc.dg/c99-tag-1.c index 2936361..e93d3bc 100644 --- a/gcc/testsuite/gcc.dg/c99-tag-1.c +++ b/gcc/testsuite/gcc.dg/c99-tag-1.c @@ -124,7 +124,7 @@ foo (void)        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 } */ +      /* { dg-error "wrong|forward" "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 } */ @@ -132,5 +132,20 @@ foo (void)        /* { dg-error "wrong" "wrong tag type" { target *-*-* } 131 } */        struct w;      } +    /* When explicitly shadowed to be a tag of a different type, references +       to the new type of tag must be accepted and those to the old type +       rejected.  */ +    { +      union s0; +      union s0 *x0; +      union s1; +      struct s1 *x1; /* { dg-bogus "warning" "warning in place of error" } */ +      /* { dg-error "wrong" "wrong tag type" { target *-*-* } 142 } */ +      union s2; +      union s2 *x2; +      union s3; +      struct s3 *x3; /* { dg-bogus "warning" "warning in place of error" } */ +      /* { dg-error "wrong" "wrong tag type" { target *-*-* } 147 } */ +    }    }  } | 
