On 04/23/2015 02:46 PM, Marek Polacek wrote:
This PR points out a problem with enum forward declarations (so C++ is out as
these are forbidden in C++).   If we forward declare an enum, and later on
declare the enum with __attribute__ ((packed)), the attribute is ignored.  The
reason is that when we first see the forward declaration, parser_xref_tag sets
up a forward-reference node, which has a default layout like unsigned int, so
among other things it does

   TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node);

But then in finish_enum we were confused: the code thinks that the precision
was specified with the mode attribute so it uses wrong TYPE_PRECISION.  After
playing with this a bit, I think easiest fix is to check for a mode attribute.
If we can't find it, we know that TYPE_PRECISION was set when processing the
forward declaration.
We also need to copy TYPE_ALIGN, otherwise subsequent layout_type won't DTRT.

While at it, I noticed that we don't test the "specified mode too small" error
at all, so I've added enum-mode-1.c test.

It's unclear what to do with a combination of "packed" and "mode" attributes; I
suppose that should be invalid, but I'm not changing it now.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2015-04-23  Marek Polacek  <pola...@redhat.com>

        PR c/52085
        * c-decl.c (finish_enum): Copy over TYPE_ALIGN.  Also check for "mode"
        attribute.

        * gcc.dg/enum-incomplete-2.c: New test.
        * gcc.dg/enum-mode-1.c: New test.
What happens if we have used the enum inside an aggregate? Can we just blindly change the alignment/precision like that?

My inclination would to to issue an error if we had a forward enum decl followed by a later packed enum.

jeff

Reply via email to