<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Jan 14, 2016, at 10:28 PM, James Y Knight <<a href="mailto:jyknight@google.com" class="">jyknight@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">(Sorry for the duplicate mail, Richard, I accidentally sent a copy only to you before.)<br class=""><div class="gmail_extra"><br class=""><div class="gmail_quote">On Thu, Jan 14, 2016 at 10:26 PM, Richard Smith via cfe-dev <span dir="ltr" class=""><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank" class="">cfe-dev@lists.llvm.org</a>></span> wrote:<br class=""><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"><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><div class="h5"><span style="color:rgb(34,34,34)" class=""> [1]: That's not completely true, as it's possible to create an object that is underaligned for its type:</span><br class=""></div></div><div class=""><div class=""><br class=""></div><div class="">struct __attribute__((packed)) A {</div><div class=""> char k;</div><div class=""> struct B { int n; } b;</div><div class="">} a;</div><div class="">A::B *p = &a.b; // Misaligned pointer, now guaranteed OK</div><div class="">int main() {</div><div class=""> int *q = &p->n; // UB? UBSan diagnoses this member access</div><div class=""> return *q; // Obviously UB</div><div class="">}</div><div class=""><br class=""></div><div class="">It seems that we do need to have some syntactic rules for how far the known alignment propagates to handle this case; your proposed rules don't do the right thing here.</div><div class=""><br class=""></div></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">I don't think any new rules are really needed here.</div><div class=""><br class=""></div><div class="">With your example, I expect even doing "int x = a.b.n;" to be okay. The value "a.b" is actually (effectively) typed "struct A::B __attribute__((aligned(1))) *", and thus fine to access a sub-object of, as the pointer is NOT misaligned for its type! And similarly, the type of &a.b.n is "int __attribute__((aligned(1))) *", and also thus not misaligned.</div><div class=""><br class=""></div><div class="">While casting the result of "&a.b" to "A::B *" in the expression "A::B *p = &a.b" is fine (well, becomes more _explicitly_ fine with your suggested modification to the standard text), once you've done that, the new type _does_ require an alignment of alignof(int), and thus, the value of "p" is misaligned for its type. And so, you can no longer dereference it nor access members. That seems all fine and sensible to me.</div><div class=""><br class=""></div><div class="">If you need to give a name "p" to the value, you can still do like this:</div><div class=""> typedef struct A::B __attribute__((aligned(1))) misaligned_A_B;</div><div class=""> misaligned_A_B *p = &a.b;</div><div class=""> int x = p->n;</div><div class=""><br class=""></div><div class="">AFAICT, this all works today, as well.</div></div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><br class=""></div><div class="">Now, of course, the "aligned" attribute being able to reduce the alignment of a type -- but only when used in a typedef (!!!) -- is a non-standard GCC extension which is not even properly documented anywhere. And it fails to work in some places, like trying to use it as a template parameter (GCC actually diagnoses that as not working; clang silently ignores it). </div><div class=""><br class=""></div><div class="">So, I'm not saying everything is completely hunky-dory here. But I do think it's essentially a workable and sane model. </div></div></div></div>
</div></blockquote><br class=""></div><div>The question at hand is whether we should require the user to write this:</div><div> misaligned_A_B *p = &a.b;</div><div>instead of, say:</div><div> A::B *p = &a.b;</div><div> int x = *(misaligned_int*) &p->n;</div><div>because we want to reserve the right to invoke undefined behavior and propagate our “knowledge" that p is 4-byte-aligned to “improve” the 1-byte-aligned access on the next line.</div><div><br class=""></div><div>My contention is that this is a clean and elegantly simple formal model that is disastrously bad for actual users because it is no longer possible to locally work around a mis-alignment bug without tracking the entire history of the pointer. It is the sort of compiler policy that gets people to roll their eyes and ask for new options called things like -fno-strict-type-alignment which gradually get adopted by 90% of projects.</div><div><br class=""></div><div>John.</div></body></html>