On Fri, Feb 19, 2016 at 01:30:52PM -0500, Jason Merrill wrote: > On 02/19/2016 09:03 AM, Jakub Jelinek wrote: > >As described in the PR, in C++ we can have assignments > >where both the lhs and rhs are COMPONENT_REFs with TREE_ADDRESSABLE types, > >including padding, but the FIELD_DECLs are artificial fields that have > >narrower bit sizes. > >store_field in this case takes the path of bit-field handling (even when > >it has bitpos and bitsize multiples of BITS_PER_UNIT (I think that is > >necessarily true for the TREE_ADDRESSABLE types), which is incorrect, > >because the rhs is expanded in that case through expand_normal, which > >for a result type wider than the FIELD_DECL with forces it into a temporary. > >In older GCCs that just generated inefficient code (copy the rhs into a > >stack temporary, then copy that to lhs), but GCC trunk ICEs on that. > >Fixed by not taking the bit-field path in that case after verifying > >we'll be able to expand it properly using the normal store_expr. > > Won't store_expr clobber tail padding because it doesn't know about bitsize?
It doesn't clobber it, because it uses get_inner_reference, expands the inner reference (which is necessarily for something TREE_ADDRESSABLE either a MEM_REF or some decl that lives in memory), and get_inner_reference in that case gives it the bitsize/bitpos from the FIELD_DECL. Which is why in the patch I've posted there is the comparison of DECL_SIZE of the FIELD_DECL against the bitsize that is passed to store_field. > I would think that what we want is to use emit_block_move in the bit-field > path whenever we're dealing with whole bytes in memory. I'm afraid we'd need to duplicate too much code if we'd wanted to bypass all the layers in there. Jakub