This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C PATCH to improve enum and struct redefinition diagnostic (PR c/79983)
- From: Marek Polacek <polacek at redhat dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Joseph Myers <joseph at codesourcery dot com>
- Date: Tue, 6 Jun 2017 18:48:28 +0200
- Subject: C PATCH to improve enum and struct redefinition diagnostic (PR c/79983)
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=polacek at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 52C8B811A9
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 52C8B811A9
This patch brings better enum and struct redefinition diagnostic. In particular,
we'll now point to the first definition in the "originally defined here" note,
not to the forward declaration.
Now, you could argue that we don't have to be setting the location by lookup_tag
at all, because we should always have the location in TYPE_STUB_DECL, and then
we could get rid of that lookup_tag parameter completely, but I think this is
good enough for now.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2017-06-06 Marek Polacek <polacek@redhat.com>
PR c/79983
* c-decl.c (start_struct): Use the location of TYPE_STUB_DECL of
ref.
(start_enum): Use the location of TYPE_STUB_DECL of enumtype.
* gcc.dg/pr79983.c: New test.
diff --git gcc/c/c-decl.c gcc/c/c-decl.c
index f2b8096..3a0a4f5 100644
--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -7453,6 +7453,9 @@ start_struct (location_t loc, enum tree_code code, tree name,
ref = lookup_tag (code, name, true, &refloc);
if (ref && TREE_CODE (ref) == code)
{
+ if (TYPE_STUB_DECL (ref))
+ refloc = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (ref));
+
if (TYPE_SIZE (ref))
{
if (code == UNION_TYPE)
@@ -8185,7 +8188,10 @@ start_enum (location_t loc, struct c_enum_contents *the_enum, tree name)
/* Update type location to the one of the definition, instead of e.g.
a forward declaration. */
else if (TYPE_STUB_DECL (enumtype))
- DECL_SOURCE_LOCATION (TYPE_STUB_DECL (enumtype)) = loc;
+ {
+ enumloc = DECL_SOURCE_LOCATION (TYPE_STUB_DECL (enumtype));
+ DECL_SOURCE_LOCATION (TYPE_STUB_DECL (enumtype)) = loc;
+ }
if (C_TYPE_BEING_DEFINED (enumtype))
error_at (loc, "nested redefinition of %<enum %E%>", name);
diff --git gcc/testsuite/gcc.dg/pr79983.c gcc/testsuite/gcc.dg/pr79983.c
index e69de29..84aae69 100644
--- gcc/testsuite/gcc.dg/pr79983.c
+++ gcc/testsuite/gcc.dg/pr79983.c
@@ -0,0 +1,15 @@
+/* PR c/79983 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct S;
+struct S { int i; }; /* { dg-message "originally defined here" } */
+struct S { int i, j; }; /* { dg-error "redefinition of 'struct S'" } */
+
+enum E;
+enum E { A, B, C }; /* { dg-message "originally defined here" } */
+enum E { D, F }; /* { dg-error "nested redefinition of 'enum E'|redeclaration of 'enum E'" } */
+
+union U;
+union U { int i; }; /* { dg-message "originally defined here" } */
+union U { int i; double d; }; /* { dg-error "redefinition of 'union U'" } */
Marek