<div dir="ltr">(Sorry for the duplicate mail, Richard, I accidentally sent a copy only to you before.)<br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 14, 2016 at 10:26 PM, Richard Smith via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</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"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><span style="color:rgb(34,34,34)"> [1]: That's not completely true, as it's possible to create an object that is underaligned for its type:</span><br></div></div><div><div><br></div><div>struct __attribute__((packed)) A {</div><div>  char k;</div><div>  struct B { int n; } b;</div><div>} a;</div><div>A::B *p = &a.b; // Misaligned pointer, now guaranteed OK</div><div>int main() {</div><div>  int *q = &p->n; // UB? UBSan diagnoses this member access</div><div>  return *q; // Obviously UB</div><div>}</div><div><br></div><div>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><br></div></div></div></div></div></blockquote><div><br></div><div>I don't think any new rules are really needed here.</div><div><br></div><div>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><br></div><div>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><br></div><div>If you need to give a name "p" to the value, you can still do like this:</div><div>  typedef struct A::B __attribute__((aligned(1))) misaligned_A_B;</div><div>  misaligned_A_B *p = &a.b;</div><div>  int x = p->n;</div><div><br></div><div>AFAICT, this all works today, as well.</div><div><br></div><div>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><br></div><div>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><br></div></div>