<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 28 November 2016 at 15:33, John McCall via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class="">On Mon, Nov 28, 2016 at 2:48 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br></span><div class="gmail_extra"><div class="gmail_quote"><span class=""><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">(Dropping Phabricator, since this isn't really about D27163...)</div><div class="gmail_quote"><br></div><div class="gmail_quote"><span>On 28 November 2016 at 14:27, John McCall via Phabricator via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br></span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span><span>In <a href="https://reviews.llvm.org/D27163#607100" rel="noreferrer" target="_blank">https://reviews.llvm.org/D2716<wbr>3#607100</a>, @rsmith wrote:<br></span></span><span><span>> C has rather different and much less useful TBAA rules<br>
<br>
</span></span>[...] I don't think the TBAA rules are as different as you're suggesting,</blockquote><div><br></div><div>I can offhand think of at least the following differences, some of which seem fairly major:</div><div> * C does not allow changing the effective type of a declared variable, C++ does.</div></div></div></div></blockquote><div><br></div></span><div>Well, except that the name of the variable itself becomes formally unbound to an object, no?  But yes, you can change the effective type via an alias as long as you're careful to only use it through that alias, which is not permitted in C.</div><span class=""><div> </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> * C does not support struct-path TBAA in any form (its model is that lumps of memory have effective types, and it doesn't care how you got there), C++ does.</div></div></div></div></blockquote><div><br></div></span><div>You're assuming that a lump of memory can't have multiple effective types at once due to subobject overlap, which doesn't seem justified by the text.  In particular, a variable of struct type definitely has the effective type of that struct.</div></div></div></div></blockquote><div><br></div><div>Sure, but effective types are only checked when the stored value is accessed, which doesn't happen when naming a member of a struct or union, only at the subsequent assignment or lvalue conversion, at which point the lvalue expression has the type of the accessed subobject, so is presumably valid per C11 6.5/7. (The lvalue expression won't have the type of some enclosing struct here regardless of whether you used that struct type to form an lvalue designating one of its members.)</div><div><br></div><div>If we really were supposed to imagine all objects enclosing the accessed object for the purpose of C11 6.5/7, it's missing a rule allowing an lvalue expression whose type is a member of the effective type of the object to access the object. (It has the opposite rule, in order to allow accesses of lvalues denoting entire structs to access the values stored in scalar subobjects.)</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"><span class=""><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> * C allows any assignment to a union member to change the effective type, no matter whether it's locally determinable that you're storing to a union member, C++ requires the assignment's LHS to be a union member access.</div><div> * C only permits common initial sequence shenanigans for unions where the union type is visible, C++ permits it anywhere.</div></div></div></div></blockquote><div><br></div></span><div>The union rules in C are all over the place.</div></div></div></div></blockquote><div><br></div><div>Agreed :)</div><div> </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>  I gave up trying to pretend that C has consistent union semantics a long time ago.</div><span class=""><div> </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"><span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">except that C++ actually tries to provide specific rules for unions (that don't match what users actually want). </blockquote><div><br></div></span><div>In what way don't C++'s union rules match user expectations where C's rules do? Do you mean type punning via unions? C doesn't allow that either (or maybe it does, if you think a footnote carries more normative weight than rules in the main text).</div></div></div></div></blockquote><div> </div></span><div>I was careful to say "what users actually want".  Users *want* type punning via unions. C's rules are contradictory because, as I read it, the committee has never been able to come to a consensus about how to formalize allowing type punning via unions without breaking the entire model — and to be fair, I don't know how to do that either.  But I would say that the expressed user desires are pretty clear here.</div></div></div></div></blockquote><div><br></div><div>Interesting. What I see from users is a strong desire to be able to do bitwise reinterpretation of values /somehow/, not necessarily to type-pun through unions, which I think is subtly but importantly different. The C DRs list has some implication that the C committee at some point intended to make type-punning through unions work, but failed to actually make the necessary changes in the wording (and all that we have left is a footnote).</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>Anyway, this is not actually important here, and I have not seen any code that falls into the cracks between language standards here, at least not under LLVM's intentionally-more-permissive-<wbr>than-standardized application of TBAA.</div></div></div></div></blockquote><div><br></div><div>I've seen plenty of programs that would be valid under some interpretations of C's rules, but not under C++'s rules. But since we effectively provide the C++ rules in all cases regardless, I agree this is not relevant for the issue at hand.</div></div></div></div>