[C] Fix bogus nested enum error message
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 8 Aug 2019 17:12:05 +0000 (17:12 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 8 Aug 2019 17:12:05 +0000 (17:12 +0000)
For:

    enum a { A };
    enum a { B };

we emit a bogus error about nested definitions before the real error:

foo.c:2:6: error: nested redefinition of ‘enum a’
    2 | enum a { B };
      |      ^
foo.c:2:6: error: redeclaration of ‘enum a’
foo.c:1:6: note: originally defined here
    1 | enum a { A };
      |      ^

This is because we weren't clearing C_TYPE_BEING_DEFINED once the
definition was over.

I think it's OK to clear C_TYPE_BEING_DEFINED even for a definition
that actually is nested (and so whose outer definition is still open),
since we'll already have given an error by then.  It means that second
and subsequent attempts to define a nested enum will usually get the
redeclaration error instead of the nested error, but that seems just
as accurate (nested_first and nested_second in the test).  The only
exception is if the first nested enum was also invalid by being empty,
but then the enum as a whole has already produced two errors
(nested_empty in the test).

2019-08-08  Richard Sandiford  <richard.sandiford@arm.com>

gcc/c/
* c-decl.c (finish_enum): Clear C_TYPE_BEING_DEFINED.

gcc/testsuite/
* gcc.dg/pr79983.c (enum E): Don't allow an error about nested
definitions.
* gcc.dg/enum-redef-1.c: New test.

From-SVN: r274213

gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/enum-redef-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr79983.c

index 4944696a1d6750f80864bce7800da47be9b0a03f..533aebc40c3d677bfac2ae2dc06eef183677cc38 100644 (file)
@@ -1,3 +1,7 @@
+2019-08-08  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * c-decl.c (finish_enum): Clear C_TYPE_BEING_DEFINED.
+
 2019-08-08  Jakub Jelinek  <jakub@redhat.com>
 
        * c-typeck.c (c_finish_omp_clauses): For C_ORT_OMP
index f85f481eb51c4d63985eef9f14f919e833984c9f..9859cc7b22f7822d942a649e6b0f67f78c446c58 100644 (file)
@@ -8781,6 +8781,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
       && !in_sizeof && !in_typeof && !in_alignof)
     struct_parse_info->struct_types.safe_push (enumtype);
 
+  C_TYPE_BEING_DEFINED (enumtype) = 0;
+
   return enumtype;
 }
 
index 6ed8aabaec87cbdf80396e18544ba1d988fa0587..a9f6c54aa849d90c3e45dc6e9439f760bd24c265 100644 (file)
@@ -1,3 +1,9 @@
+2019-08-08  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * gcc.dg/pr79983.c (enum E): Don't allow an error about nested
+       definitions.
+       * gcc.dg/enum-redef-1.c: New test.
+
 2019-08-08  Marek Polacek  <polacek@redhat.com>
 
        PR c++/87519 - bogus warning with -Wsign-conversion.
diff --git a/gcc/testsuite/gcc.dg/enum-redef-1.c b/gcc/testsuite/gcc.dg/enum-redef-1.c
new file mode 100644 (file)
index 0000000..b3fa6cb
--- /dev/null
@@ -0,0 +1,29 @@
+enum a { A };
+enum a { B }; /* { dg-bogus "nested redefinition" } */
+/* { dg-error "redeclaration of 'enum a'" "" { target *-*-* } .-1 } */
+
+enum empty {}; /* { dg-error "empty enum is invalid" } */
+enum empty {}; /* { dg-bogus "nested redefinition" } */
+/* { dg-error "empty enum is invalid" "" { target *-*-* } .-1 } */
+
+enum nested_first {
+  C1 = sizeof(enum nested_first { C1a }), /* { dg-error "nested redefinition of 'enum nested_first" } */
+  C2 = sizeof(enum nested_first { C2a }) /* { dg-error "redeclaration of 'enum nested_first'" "" } */
+};
+
+enum nested_second {
+  D1,
+  D2 = sizeof(enum nested_second { D2a }), /* { dg-error "nested redefinition of 'enum nested_second" } */
+  D3 = sizeof(enum nested_second { D3a }) /* { dg-error "redeclaration of 'enum nested_second'" "" } */
+};
+
+enum nested_repeat { E };
+enum nested_repeat { /* { dg-error "redeclaration of 'enum nested_repeat'" "" } */
+  F = sizeof(enum nested_repeat { Fa }) /* { dg-error "nested redefinition of 'enum nested_repeat" } */
+};
+
+enum nested_empty {
+  G1 = sizeof(enum nested_empty {}), /* { dg-error "nested redefinition of 'enum nested_empty" } */
+  /* { dg-error "empty enum is invalid" "" { target *-*-* } .-1 } */
+  G2 = sizeof(enum nested_empty { G2a })
+};
index 84aae691318eefb95a72d6461c9aba272663eca5..1e292d4210810d00c1c12786b2ca50f43b19bf70 100644 (file)
@@ -8,7 +8,7 @@ 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'" } */
+enum E { D, F }; /* { dg-error "redeclaration of 'enum E'" } */
 
 union U;
 union U { int i; }; /* { dg-message "originally defined here" } */