[committed] c: Fix ICE for nested enum redefinitions with/without fixed underlying type [PR112571]
Checks
Commit Message
Bug 112571 reports an ICE-on-invalid for cases where an enum is
defined, without a fixed underlying type, inside the enum type
specifier for a definition of that same enum with a fixed underlying
type.
The ultimate cause is attempting to access ENUM_UNDERLYING_TYPE in a
case where it is NULL. Avoid this by clearing
ENUM_FIXED_UNDERLYING_TYPE_P in thie case of inconsistent definitions.
Bootstrapped wth no regressions for x86_64-pc-linux-gnu.
PR c/112571
gcc/c/
* c-decl.cc (start_enum): Clear ENUM_FIXED_UNDERLYING_TYPE_P when
defining without a fixed underlying type an enumeration previously
declared with a fixed underlying type.
gcc/testsuite/
* gcc.dg/c23-enum-9.c, gcc.dg/c23-enum-10.c: New tests.
---
Applied to mainline. Should also be backported to GCC 13 branch (the
oldest version with support for enums with fixed underlying types),
after waiting to see if any problems arise with the patch on mainline,
subject to changing -std=c23 to -std=c2x for the older version and
making sure the patch does indeed work on the older version (there
have been significant changes renaming to redefinitions of tagged
types in GCC 14 as part of Martin's tag compatibility work).
@@ -9905,8 +9905,11 @@ start_enum (location_t loc, struct c_enum_contents *the_enum, tree name,
if (ENUM_FIXED_UNDERLYING_TYPE_P (enumtype)
&& fixed_underlying_type == NULL_TREE)
- error_at (loc, "%<enum%> declared with but defined without "
- "fixed underlying type");
+ {
+ error_at (loc, "%<enum%> declared with but defined without "
+ "fixed underlying type");
+ ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) = false;
+ }
the_enum->enum_next_value = integer_zero_node;
the_enum->enum_type = enumtype;
new file mode 100644
@@ -0,0 +1,6 @@
+/* PR c/112571. */
+/* { dg-do compile } */
+/* { dg-options "-std=c23" } */
+
+enum X : typeof (enum X { A }); /* { dg-error "declared with but defined without fixed underlying type" } */
+/* { dg-error "invalid 'enum' underlying type" "invalid" { target *-*-* } .-1 } */
new file mode 100644
@@ -0,0 +1,8 @@
+/* PR c/112571. */
+/* { dg-do compile } */
+/* { dg-options "-std=c23" } */
+
+enum h : typeof (enum h { D }) { D }; /* { dg-error "declared with but defined without fixed underlying type" } */
+/* { dg-error "invalid 'enum' underlying type" "invalid" { target *-*-* } .-1 } */
+/* { dg-error "nested redefinition" "nested" { target *-*-* } .-2 } */
+/* { dg-error "conflicting redefinition" "conflicting" { target *-*-* } .-3 } */