This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: underlying type for enums


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]