<div dir="ltr">On Mon, Nov 30, 2015 at 2:31 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="">On Mon, Nov 30, 2015 at 11:33 AM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@gmail.com" target="_blank">rjmccall@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">rjmccall added a comment.<br>
<span><br>
In <a href="http://reviews.llvm.org/D14980#298754" rel="noreferrer" target="_blank">http://reviews.llvm.org/D14980#298754</a>, @rsmith wrote:<br>
<br>
> GCC's behavior (`aligned` on a field specifies the alignment of the start of that field) makes a little more sense to me than Clang's behavior (the type and alignment of a field specify a flavour of storage unit, and the field goes in the next such storage unit that it fits into), but both seem defensible.<br>
<br>
<br>
</span>Are you saying that `aligned` on a bit-field always starts new storage on GCC?</blockquote><div><br></div></span><div>Not exactly. For instance, given</div><div><br></div><div><div>struct X {</div><div>  __attribute__((aligned(1))) char a : 2, b : 2, c : 2, d : 2;</div><div>} x = {0, 1, 2, 3};</div></div><div><br></div><div>... GCC produces</div><div><br></div><div><div>x:</div><div>        .byte   0</div><div>        .byte   1</div><div>        .byte   2</div><div>        .byte   3</div></div><div><br></div><div>The result is the same for any other bit-field type (except that we get tail padding for types wider than 4 bytes), and in particular, we don't allocate a new storage unit for 'b' and 'd' when the type is 'short'; we just insert padding to get to a 1-byte-aligned boundary.</div></div></div></div></blockquote><div><br></div><div>This is what I meant by starting new storage: it never fills space in the previous byte.  And now I realize that of course that's the major effect of this patch.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>The rule that a bit-field can't straddle a naturally-aligned storage unit for the underlying type still applies (for non-packed structs).</div></div></div></div></blockquote><div><br></div><div>This is going to require significant surgery to this function.  And it looks like this rule should apply to ms_struct layout as well.</div><div><br></div><div>In other words:</div><div>  - The offset of the field is rounded up to the next multiple of the explicit alignment that (unless the field is packed) does not cause the field to straddle its natural alignment boundary, which can happen if its explicit alignment is less than its natural alignment.</div><div>  - On platforms (like ARM) that ignore the natural alignment of bit-fields, this seems to have no effect except to always start a new byte.  We seem to be getting this wrong, too.</div><div>  - Both the field's natural alignment and its explicit alignment, as capped by the max field alignment, contribute to the alignment of the aggregate, unless the field is packed.  Again, currently wrong.</div><div><br></div><div>John.</div></div>
</div></div>