This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C PATCH to improve enum and struct redefinition diagnostic (PR c/79983)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]