Skip to content
Snippets Groups Projects
Commit e0997c14 authored by Joseph Myers's avatar Joseph Myers
Browse files

c: C2x enums with fixed underlying type [PR61469]

C2x adds support for enums with a fixed underlying type specified
("enum e : long long;" and similar).  Implement this in the C front
end.  The same representation is used for these types as in C++, with
two macros moved from cp-tree.h to c-common.h.

Such enums can have bool as the underlying type, and various C
front-end code checking for boolean types is adjusted to use a new
C_BOOLEAN_TYPE_P to handle such enums the same way as bool.  (Note
that for C++ we have bug 96496 that enums with underlying type bool
don't work correctly there.)

There are various issues with the wording for such enums in the
current C2x working draft (including but not limited to wording in the
accepted paper that failed to make it into the working draft), which I
intend to raise in NB comments.  I think what I've implemented and
added tests for matches the intent.

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

	PR c/61469

gcc/c-family/
	* c-common.h (ENUM_UNDERLYING_TYPE, ENUM_FIXED_UNDERLYING_TYPE_P):
	New.  Moved from cp/cp-tree.h.
	* c-warn.cc (warnings_for_convert_and_check): Do not consider
	conversions to enum with underlying type bool to overflow.

gcc/c/
	* c-convert.cc (c_convert): Handle enums with underlying boolean
	type like bool.
	* c-decl.cc (shadow_tag_warned): Allow shadowing declarations for
	enums with enum type specifier, but give errors for storage class
	specifiers, qualifiers or alignment specifiers in non-definition
	declarations of such enums.
	(grokdeclarator): Give error for non-definition use of type
	specifier with an enum type specifier.
	(parser_xref_tag): Add argument has_enum_type_specifier.  Pass it
	to lookup_tag and use it to set ENUM_FIXED_UNDERLYING_TYPE_P.
	(xref_tag): Update call to parser_xref_tag.
	(start_enum): Add argument fixed_underlying_type.  Complete enum
	type with a fixed underlying type given in the definition.  Give
	error for defining without a fixed underlying type in the
	definition if one was given in a prior declaration.  Do not mark
	enums with fixed underlying type as packed for -fshort-enums.
	Store the enum type in the_enum.
	(finish_enum): Do not adjust types of values or check their range
	for an enum with a fixed underlying type.  Set underlying type of
	enum and variants.
	(build_enumerator): Check enumeration constants for enum with
	fixed underlying type against that type and convert to that type.
	Increment in the underlying integer type, with handling for bool.
	(c_simulate_enum_decl): Update call to start_enum.
	(declspecs_add_type): Set specs->enum_type_specifier_ref_p.
	* c-objc-common.cc (c_get_alias_set): Use ENUM_UNDERLYING_TYPE
	rather than recomputing an underlying type based on size.
	* c-parser.cc (c_parser_declspecs)
	(c_parser_struct_or_union_specifier, c_parser_typeof_specifier):
	Set has_enum_type_specifier for type specifiers.
	(c_parser_enum_specifier): Handle enum type specifiers.
	(c_parser_struct_or_union_specifier): Update call to
	parser_xref_tag.
	(c_parser_omp_atomic): Check for boolean increment or decrement
	using C_BOOLEAN_TYPE_P.
	* c-tree.h (C_BOOLEAN_TYPE_P): New.
	(struct c_typespec): Add has_enum_type_specifier.
	(struct c_declspecs): Add enum_type_specifier_ref_p.
	(struct c_enum_contents): Add enum_type.
	(start_enum, parser_xref_tag): Update prototypes.
	* c-typeck.cc (composite_type): Allow for enumerated types
	compatible with bool.
	(common_type, comptypes_internal, perform_integral_promotions):
	Use ENUM_UNDERLYING_TYPE.
	(parser_build_binary_op, build_unary_op, convert_for_assignment)
	(c_finish_return, c_start_switch, build_binary_op): Check for
	boolean types using C_BOOLEAN_TYPE_P.

gcc/cp/
	* cp-tree.h (ENUM_FIXED_UNDERLYING_TYPE_P, ENUM_UNDERLYING_TYPE):
	Remove.  Moved to c-common.h.

gcc/testsuite/
	* gcc.dg/c11-enum-4.c, gcc.dg/c11-enum-5.c, gcc.dg/c11-enum-6.c,
	gcc.dg/c2x-enum-6.c, gcc.dg/c2x-enum-7.c, gcc.dg/c2x-enum-8.c,
	gcc.dg/gnu2x-enum-1.c: New tests.
parent 96069d84
No related branches found
No related tags found
No related merge requests found
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment