On Mon, Jan 23, 2017 at 8:49 AM, Nathan Sidwell <nat...@acm.org> wrote: > This patch addresses 79118, where we ICE on a constexpr involving bitfields > in an unnamed struct (unnamed struct members are a g++ extension). > > This is really a band-aid, because our internal representation BITFIELD_REF > and the (premature) optimizations it encourages is incompatible with > constexpr requirements. There's already signs of that with Jakub's code to > deal with fold turning things like: > int foo: 5; > int baz: 3; > ... > ptr->baz == cst > turns into the moral equivalent of (little endian example) > ((*(unsigned char *)ptr & 0xe0) == (cst << 5) > > In this particular case we've also made the base object the containing > class, not the unnamed struct member. That means we're looking in the wrong > CONSTRUCTOR and see CONSTRUCTOR_NO_IMPLICIT_ZERO is true. Whereas for the > subobj's CONSTRUCTOR it is false.
Why is it false? > With this patch we end up thinking this > is an OK constexpr of value zero, whereas it's actually an uninitialized > bitfield read. > > But I think we could already make that mistake given the above example & > fold's behaviour. If 'ptr->foo' has been initialized, we'll construct a > value using just that field and think we have a valid initialization of > ptr->baz too. > > The equivalent testcase using non-bitfields has a base object of the unnamed > struct member, and behaves correctly (given this is an extension anyway). > > The right solution is to fix the IR. In the C++ FE have BITFIELD_REF (or a > new node) look much more like COMPONENT_REF (or even be COMPONENT_REF, but I > suspect lots of places think ADDR (COMPONENT_REF (...)) is legit). And > lower it to the middle-end generic representation in cp_genericize. I don't > think this is the right time for a change of that magnitude though. Yes, for this and other reasons we should do constexpr evaluation on the pre-genericized trees. > Perhaps for now we should just always err on the side of safety, and behave > as-if uninitialized if we fall of the end of looking for a bitfield? That makes sense. Jason