diff options
author | Joseph Myers <josmyers@redhat.com> | 2024-01-31 21:39:53 +0000 |
---|---|---|
committer | Joseph Myers <josmyers@redhat.com> | 2024-01-31 21:39:53 +0000 |
commit | d22d1a9346f27db41459738c6eb404f8f0956e6f (patch) | |
tree | a93a318d7de1910284f57126083cddcc180583f7 | |
parent | 8123f3ca3fd891034a8366518e756f161c4ff40d (diff) | |
download | gcc-d22d1a9346f27db41459738c6eb404f8f0956e6f.zip gcc-d22d1a9346f27db41459738c6eb404f8f0956e6f.tar.gz gcc-d22d1a9346f27db41459738c6eb404f8f0956e6f.tar.bz2 |
c: Fix ICE for nested enum redefinitions with/without fixed underlying type [PR112571]
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.
-rw-r--r-- | gcc/c/c-decl.cc | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/c23-enum-10.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/c23-enum-9.c | 8 |
3 files changed, 19 insertions, 2 deletions
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 8d18a3e..934e557 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -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; diff --git a/gcc/testsuite/gcc.dg/c23-enum-10.c b/gcc/testsuite/gcc.dg/c23-enum-10.c new file mode 100644 index 0000000..dd5f345 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-enum-10.c @@ -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 } */ diff --git a/gcc/testsuite/gcc.dg/c23-enum-9.c b/gcc/testsuite/gcc.dg/c23-enum-9.c new file mode 100644 index 0000000..10bb493 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-enum-9.c @@ -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 } */ |