[committed] c: Diagnose "enum tag;" after definition [PR107164]

Message ID alpine.DEB.2.22.394.2210182326090.2363097@digraph.polyomino.org.uk
State Repeat Merge
Headers
Series [committed] c: Diagnose "enum tag;" after definition [PR107164] |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Joseph Myers Oct. 18, 2022, 11:26 p.m. UTC
  As noted in bug 101764, a declaration "enum tag;" is invalid in
standard C after a definition, as well as when no definition is
visible; we had a pedwarn-if-pedantic for the forward declaration
case, but were missing one for the other case.  Add that missing
diagnostic (if pedantic only).

(These diagnostics will need to be appropriately conditioned when
support is added for C2x enums with fixed underlying type, since "enum
tag : type;" is OK both before and after a definition.)

Bootstrapped with no regressions for x86_64-pc-linux-gnu.

	PR c/107164

gcc/c/
	* c-decl.cc (shadow_tag_warned): If pedantic, diagnose "enum tag;"
	with previous declaration visible.

gcc/testsuite/
	* gcc.dg/c99-tag-4.c, gcc.dg/c99-tag-5.c, gcc.dg/c99-tag-6.c: New
	tests.
  

Patch

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index bcb4d7b66fe..80f6e912187 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -4814,6 +4814,20 @@  shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
 	      warned = 1;
 	      pending_xref_error ();
 	    }
+	  else if (declspecs->typespec_kind != ctsk_tagdef
+		   && declspecs->typespec_kind != ctsk_tagfirstref
+		   && declspecs->typespec_kind != ctsk_tagfirstref_attrs
+		   && code == ENUMERAL_TYPE)
+	    {
+	      bool warned_enum = false;
+	      if (warned != 1)
+		warned_enum = pedwarn (input_location, OPT_Wpedantic,
+				       "empty declaration of %<enum%> type "
+				       "does not redeclare tag");
+	      if (warned_enum)
+		warned = 1;
+	      pending_xref_error ();
+	    }
 	  else
 	    {
 	      pending_invalid_xref = NULL_TREE;
diff --git a/gcc/testsuite/gcc.dg/c99-tag-4.c b/gcc/testsuite/gcc.dg/c99-tag-4.c
new file mode 100644
index 00000000000..9ff3ccb8d4b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-tag-4.c
@@ -0,0 +1,8 @@ 
+/* Test for handling of tags.  "enum foo;" is invalid after an existing
+   declaration (does not redeclare the tag) as well as before: bug 107164.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+enum e1; /* { dg-error "ISO C forbids forward references to 'enum' types" } */
+enum e2 { E };
+enum e2; /* { dg-error "empty declaration of 'enum' type does not redeclare tag" } */
diff --git a/gcc/testsuite/gcc.dg/c99-tag-5.c b/gcc/testsuite/gcc.dg/c99-tag-5.c
new file mode 100644
index 00000000000..97fcc75bc26
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-tag-5.c
@@ -0,0 +1,8 @@ 
+/* Test for handling of tags.  "enum foo;" is invalid after an existing
+   declaration (does not redeclare the tag) as well as before: bug 107164.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic" } */
+
+enum e1; /* { dg-warning "ISO C forbids forward references to 'enum' types" } */
+enum e2 { E };
+enum e2; /* { dg-warning "empty declaration of 'enum' type does not redeclare tag" } */
diff --git a/gcc/testsuite/gcc.dg/c99-tag-6.c b/gcc/testsuite/gcc.dg/c99-tag-6.c
new file mode 100644
index 00000000000..8307217523c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-tag-6.c
@@ -0,0 +1,9 @@ 
+/* Test for handling of tags.  "enum foo;" is invalid after an existing
+   declaration (does not redeclare the tag) as well as before: bug 107164.
+   Test this is not diagnosed without -pedantic.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c99" } */
+
+enum e1;
+enum e2 { E };
+enum e2;