This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: underlying type for enums
- From: Jamie Lokier <jamie at shareable dot org>
- To: Richard Henderson <rth at redhat dot com>, jsm at polyomino dot org dot uk, Jason Merrill <jason at redhat dot com>, gcc at gcc dot gnu dot org
- Date: Wed, 3 Dec 2003 02:51:07 +0000
- Subject: Re: underlying type for enums
- References: <20031202090652.GC32317@redhat.com>
Richard Henderson wrote:
> The top level problem that led me to the ENUM_BITFIELD patch earlier
> this evening comes from wanting to get rid of this hack:
>
> - /* We don't want to risk changing the type of the switch condition,
> - lest stmt.c get the wrong impression about enumerations. */
> - if (TREE_CODE (SWITCH_COND (switch_expr)) == NOP_EXPR)
> - ret = gimplify_expr (&TREE_OPERAND (SWITCH_COND (switch_expr), 0),
> - pre_p, NULL, is_gimple_val, fb_rvalue);
>
> The root of the problem is that the C front end currently sets
> TYPE_MIN/MAX_VALUE for an enumeration based on the values of the
> enumerators. Since an enum type can hold values other than the
> enumerators, this is clearly wrong, [...]
It would be nice to be able to define enum types with an attribute
extension that tells GCC to assume the range is limited to enumerators,
> and it can lead expand_end_case_type to believe that a default case
> is unreachable.
...so that code to handle the default case can be omitted (and a
warning given) when those types are used in a switch statement.
> Perhaps I should just set the compatible type to int or unsigned int
> (or larger ad needed), leave TYPE_MIN/MAX_VALUE set correctly for those
> types, and handle the bit-field too small warning another way. It would
> not be hard, for instance, to store the required width in lang_type.
If you were to say the type is an integer of the minimum number of
bits required to represent all the enumerators, and set
TYPE_MIN/MAX_VALUE according to that, will GCC assume that range for
the purpose of optimisation?
In particular, if you do that can GCC generate a sequence of
shifts/masks that modify bits outside the bitfield s.e in this example?
typedef enum { RED, GREEN, YELLOW } E;
struct { E e : 2; unsigned f : 1; } s;
E e2;
*(char *)&e2 = 4;
// Can this modify s.f?
s.e = (__typeof__(s.e)) e2;
The simplest implementation sequence, if GCC could assume that a value
with that enum type is in the range 0..3, for the final statement
would be something like:
*(char*)s = (*(char*)s & ~3) | e2;
If GCC could not make that assumption, it would be:
*(char*)s = (*(char*)s & ~3) | (e2 & 3);
-- Jamie