OK!<div><br></div><div>With all that discussion, here is an updated patch. I've included most of the tricky test cases described here (where they seemed valuable) along with lots of comments to help document some of this discussion and the conclusions.</div>
<div><br></div><div>Any test cases missing? Anything else I need to do to get this ready for commit?</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Sep 12, 2012 at 3:46 AM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div class="h5"><div><div>On Sep 12, 2012, at 1:03 AM, Richard Smith wrote:</div>
<blockquote type="cite">On Tue, Sep 11, 2012 at 10:52 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div style="word-wrap:break-word"><br><div><div><div><div>On Sep 11, 2012, at 8:19 PM, Richard Smith wrote:</div><br><blockquote type="cite">On Tue, Sep 11, 2012 at 6:47 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br>

<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word"><div><div><div><div>On Sep 11, 2012, at 6:29 PM, Chandler Carruth wrote:</div><blockquote type="cite"><div class="gmail_extra"><div class="gmail_quote">On Tue, Sep 11, 2012 at 6:09 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br>



<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>On Tue, Sep 11, 2012 at 6:04 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></span> wrote:<br>



</div></div><div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>On Sep 11, 2012, at 4:41 PM, Richard Smith wrote:<br>
> On Tue, Sep 11, 2012 at 11:33 AM, John McCall <<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>> wrote:<br>
> On Sep 11, 2012, at 11:07 AM, Chandler Carruth wrote:<br>
> > On Fri, Aug 31, 2012 at 1:01 PM, Eli Friedman <<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>> wrote:<br>
</div><div>> >> Another nasty case I just thought of:<br>
> >><br>
> >> struct x { int i : 24; };<br>
> >> struct y { int i : 24; char j; };<br>
> >> union z {<br>
> >>   struct x x;<br>
> >>   struct y y;<br>
> >> };<br>
> >> union z a;<br>
> >> void f(int i) {<br>
> >>   a.x.i = i;<br>
> >> }<br>
> >> void g(char j) {<br>
> >>   a.y.j = j<br>
> >> }<br>
> >><br>
> >> The two writes are to separate memory locations. :)<br>
> ><br>
> > Wait, hold on... I'm deeply confused. Maybe because I don't know how C11 unions work?<br>
> ><br>
> > With C++11, only one side of the union is allowed to be active, and so I don't think they are separate memory locations?<br>
><br>
> I agree that this isn't a problem, but the analysis is a bit more complicated;<br>
> it hinges on the fact that it's okay to *read* from an inactive union member<br>
> under the common-prefix exception, but it's not okay to *write* to it.  The<br>
> same analysis applies in both standards:<br>
><br>
> Is this still OK if the extra union member is volatile? Chandler and I have discussed this, and it's far from clear that it would be. (In particular, we can conceive of a seemingly-reasonable case where the union sits on an MMIO port, and only the fourth byte has volatile semantics.)<br>





<br>
</div>I see no reason why making the member volatile changes anything.<br>
Other members in the union can be assumed not to exist, because the<br>
active union member *must* be the one we're assigning to — indeed,<br>
in C such an assignment is how you change the active union member.<br></blockquote><div><br></div></div></div><div>I'm talking about the load-widening case, not the store-widening. Given:</div><div><br></div><div>union U {</div>




<div>  struct X { int a : 24; volatile char b; } x;</div><div>  struct Y { int c : 24; } y;</div><div>};</div><div><br></div><div>... if x is the active member, and we load y.c, can we really load from the storage location containing x.b?</div>




</div>
</blockquote></div><br></div><div class="gmail_extra">After going back and forth a few times amongst the committee members here, we propose this:</div><div class="gmail_extra"><br></div><div class="gmail_extra">This is a defect. We should disallow reading from the common prefix of a union using a non-active member if there are any volatile members following the common prefix. There doesn't appear to be any way to support these union types and common-prefix reads and the committee's express desire that load widening is a valid compiler optimization.</div>



<div class="gmail_extra"><br></div><div class="gmail_extra">Reasons why this truly seems like a defect:</div><div class="gmail_extra"><br></div><div class="gmail_extra">1) We can't even load widen through the padding bytes:</div>



<div class="gmail_extra"><br></div><div class="gmail_extra">union U {<br>  struct X { int a : 24; volatile char b; } x;</div><div class="gmail_extra">  struct Y { int a : 24; int c; } y;</div><div class="gmail_extra">};</div>



<div class="gmail_extra"><br></div><div class="gmail_extra">2) We can't even load widen when the next field in all members after the common prefix is non-volatile:</div><div class="gmail_extra"><br></div><div class="gmail_extra">



union U {<br>  struct X { int a : 33; char b; volatile char c; } x;</div><div class="gmail_extra">  struct Y { int a : 33; } y;</div><div class="gmail_extra">};</div><div class="gmail_extra"><br></div><div class="gmail_extra">



<br></div><div class="gmail_extra">Seem plausible?</div>
</blockquote></div><br></div></div><div>I could accept this as a defect.  I don't think it's required.</div><div><br></div><div>For example, I claim that, if we need x and z, we are allowed to use a 32-bit</div><div>


load here (although, granted, it might not be a good idea):</div><div>  struct [[align(4)]] A {</div><div>    char x;</div><div>    volatile char y;</div><div>    char z;</div><div>  };</div></div></blockquote><div><br></div>


<div><div>[The common initial sequence exemption only applies to structs as union members, so that case is fine. Assuming these are each wrapped in a struct...]</div></div></div></blockquote><div><br></div></div></div><div>

I think you misread what I wrote or assumed it away.  I wrote, and meant, a struct;  there's no union here.</div></div></div></blockquote><div><br></div><div>Yes, you're absolutely right, I misread the 'struct' as 'union'. My apologies.</div>

<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div>I am saying that I believe it is legal to widen a load so that it spans other data that happens to include a volatile object.  That is, it is perfectly legal to touch a volatile object when not requested to, as long as you (1) implement the actual requested accesses exactly as the abstract machine specifies, (2) don't introduce data races as covered by [intro.memory], and (3) don't violate your implementation-defined semantics for volatile accesses.</div>

</div></div></blockquote><div><br></div><div>I see. C++ does not include C's statement that "what constitutes an access to an object that has volatile-qualified type is implementation-defined", but I suppose we can assume it's intended, based on the non-normative text in [<a href="http://dcl.type.cv/" target="_blank">dcl.type.cv</a>]p7 which says that the intent is to match C.</div>

</div>
</blockquote></div><br></div></div><div>Right, that's what I'm arguing.  We have the flexibility to restrict volatile semantics so that we don't have to obsessively worry about volatile chars in every nook and shadow.</div>
<div><br></div><div>That said, I agree that we should also pursue the defect that Chandler described.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>John.</div></font></span></div></blockquote></div><br>
</div>