summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-11 11:50:29 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2001-06-11 11:50:29 +0000
commitea97174b038a2860ae13c303a5a1e03cdc7eb4a6 (patch)
treef31c4c85770575b6701e3a1a5db7bbfed83e24dd /gcc
parenta85760fe5e8868fd808e29ef6fc9b3e0a959ebdb (diff)
downloadgcc-ea97174b038a2860ae13c303a5a1e03cdc7eb4a6.tar.gz
* c-decl.c (xref_tag): Don't return previous tags of wrong type.
testsuite: * gcc.dg/c99-tag-1.c: Add more tests. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@43179 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/c-decl.c17
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/c99-tag-1.c17
4 files changed, 36 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ad24ae54802..fe8a6199aa4 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 78c852e214f..b68f7721a58 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 467a5e4316f..d1255208049 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 293636154ad..e93d3bcf0b4 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 } */
+ }
}
}