https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127623
Bug ID: 127623
Summary: ICE: 'verify_type' failed ('TYPE_CANONICAL' is not
compatible) for an anonymous enum with underlying type
bool (C23)
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: ice-checking, ice-on-valid-code
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: captainnemo9292 at gmail dot com
Target Milestone: ---
An anonymous enumeration with a fixed underlying type of bool (C23) ICEs in
checking builds as soon as the enum is finished:
enum : bool { a };
$ gcc -std=c23 -c t.c
t.c:1:15: error: 'TYPE_CANONICAL' is not compatible
<boolean_type 0x... bool public unsigned QI ...>
<enumeral_type 0x... ...>
t.c:1:15: internal compiler error: 'verify_type' failed
verify_type(tree_node const*)
rest_of_type_compilation(tree_node*, int)
finish_enum(tree_node*, tree_node*, tree_node*)
c_parser_declspecs
https://godbolt.org/z/MPvv3144b - 15.1, 15.3, 16.1, 16.2 and trunk (17.0
20260926), any -O level. Release-checking builds accept the code, so this is
checking-only. It needs both properties: a named enum (enum e : bool { a })
and an anonymous enum with any other underlying type (char, unsigned short)
compile fine.
start_enum sets the canonical type of an enum with a fixed underlying type to
that of the underlying type (c-decl.cc, TYPE_CANONICAL (enumtype) =
TYPE_CANONICAL (fixed_underlying_type)). verify_type then checks that
TYPE_CANONICAL (t) is gimple_canonical_types_compatible_p with t, and that
comparison maps ENUMERAL_TYPE to INTEGER_TYPE
(tree_code_for_canonical_type_merging) but leaves BOOLEAN_TYPE as is, so a
bool canonical type is never compatible with an enumeral type. Every other
underlying type is an INTEGER_TYPE and passes. Whether the anonymous enum
should get a canonical type of bool at all, or whether the merging code
should treat BOOLEAN_TYPE like INTEGER_TYPE here, I leave to you.
Found by fuzzing; the original testcase also redeclared the enumerator, which
is not needed.