<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi,<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Aug 4, 2020, at 18:32, David Rector via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><br class="Apple-interchange-newline"><br class=""><blockquote type="cite" class=""><div class="">On Aug 3, 2020, at 11:28 PM, Hal Finkel via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" class="">cfe-dev@lists.llvm.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><p class=""><br class=""></p><div class="moz-cite-prefix">On 8/3/20 8:45 PM, John McCall wrote:<br class=""></div><blockquote type="cite" cite="mid:833CCC19-6042-4889-B081-28EBD258FBB2@apple.com" class=""><div class="" style="font-family: sans-serif;"><div class="" style="white-space: normal;"><p dir="auto" class="">On 31 Jul 2020, at 19:50, Hal Finkel wrote:</p></div><div class="" style="white-space: normal;"><blockquote class="" style="border-left-width: 2px; border-left-style: solid; border-left-color: rgb(119, 119, 119); color: rgb(119, 119, 119); margin: 0px 0px 5px; padding-left: 5px;"><p dir="auto" class="">On 7/31/20 5:59 PM, James Y Knight wrote:</p><blockquote class="" style="border-left-width: 2px; border-left-style: solid; color: rgb(153, 153, 153); margin: 0px 0px 5px; padding-left: 5px; border-left-color: rgb(153, 153, 153);"><p dir="auto" class="">This discussion reminds me of an example I ran into a couple weeks ago, where the execution of the program is dependent precisely upon whether the ABI calls for the object to be passed indirectly, or in a register<br class=""><br class="">In the case where NVRO is triggered, the class member foo_ is fully-constructed on the first line of CreateFoo (despite appearing as if that's only constructing a local variable). In the case where the struct is small enough to fit in a register, NVRO does not apply, and in that case, foo_ isn't constructed until after CreateFoo returns.<br class=""><br class="">Therefore, I believe it's implementation-defined whether the following program has undefined behavior.<br class=""><br class=""><a href="https://godbolt.org/z/YT9zsz" moz-do-not-send="true" class="" style="color: rgb(153, 153, 153);">https://godbolt.org/z/YT9zsz</a><span class="Apple-converted-space"> </span><<a href="https://godbolt.org/z/YT9zsz" moz-do-not-send="true" class="" style="color: rgb(153, 153, 153);">https://godbolt.org/z/YT9zsz</a>><br class=""><br class="">#include <assert.h><br class=""><br class="">struct Foo {<br class=""> int x;<br class="">* // assert fails if you comment out these unused fields!<br class="">* int dummy[4];<br class="">};<br class=""><br class="">struct Bar {<br class=""> Bar() : foo_(CreateFoo()) {}<br class=""><br class=""> Foo CreateFoo() {<br class=""> Foo f;<br class=""> f.x = 55;<br class=""> assert(foo_.x == 55);<br class=""> return f;<br class=""> }<br class=""> Foo foo_;<br class="">};<br class=""><br class="">int main() {<br class=""> Bar b;<br class="">}</p></blockquote><p dir="auto" class="">Looks that way to me too. The example in 11.10.5p2 sort of makes this point as well (by pointing out that you can directly initialize a global this way).</p></blockquote></div><div class="" style="white-space: normal;"><p dir="auto" class="">It does seem hard to argue that this is invalid under the specification. To me it seems like it clearly<span class="Apple-converted-space"> </span><em class="">ought</em><span class="Apple-converted-space"> </span>to be invalid, though. Note that Clang has always emitted return address arguments as<span class="Apple-converted-space"> </span><code bgcolor="#F7F7F7" class="" style="background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; margin: 0px; padding: 0px 0.4em;">noalias</code>, so this has immediate significance.</p><p dir="auto" class="">If I were writing the specification, I would rewrite the restriction in<span class="Apple-converted-space"> </span><code bgcolor="#F7F7F7" class="" style="background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; margin: 0px; padding: 0px 0.4em;">[class.cdtor]p2</code><span class="Apple-converted-space"> </span>to say that pointers derived by naming a returned/constructed object do not formally point to the object until the function actually returns, even if the copy is elided. That would make James’s example undefined behavior.</p><p dir="auto" class="">John.</p></div></div></blockquote><p class=""><br class=""></p><p class="">I agree. It seems like we should be able to make a sanitizer detect this kind of mistake as well (although the general case will require some msan-like propagation scheme).<br class=""></p><p class=""> -Hal<br class=""></p></div></div></blockquote><div class=""><br class=""></div><div class="">On second thought I agree as well — i.e. allow both the NRVO and the noalias optimizations to be applied as they currently are, and adjust the standard so that any code which would break due to those optimizations should be considered undefined. </div><div class=""><br class=""></div><div class="">That would be consistent with the proposal of making escaping pointers within a constructor of a trivially-copyable class undefined behavior.</div><div class=""><br class=""></div><div class="">And more generally: if there are<span class="Apple-converted-space"> </span><i class="">any</i><span class="Apple-converted-space"> </span>other instances in which the compiler is currently forced to be pessimistic, just to handle a few weird usages which are technically allowed, I think by all means we should ask the standard to explicitly address those, via the same approach: the typical, more-optimizable cases should be allowed to fully optimize, by making the rare, less-optimizable cases undefined behavior. </div><div class=""><br class=""></div></div></div></blockquote><div><br class=""></div>It would be great to make some progress on the issue, but unfortunately I am unclear what the next steps should be?</div><div><br class=""></div><div>As mentioned earlier, I added a patch to add noalias under a flag (<a href="https://reviews.llvm.org/D85473" class="">https://reviews.llvm.org/D85473</a>). Are there any concerns/objections on this as a first step?</div><div><br class=""></div><div>Whether to enable it by default can then be discussed separately. IIUC from the discussion, we would need an adjustment to the standard along to lines of John’s proposal to making escaping pointers within a constructor of a trivially-copyable class undefined behavior. Are there any pointers/suggestions on how to best go about that?<br class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div class="">But in tandem, the standard should also introduce attributes that allow advanced users to explicitly opt out of those optimizations (e.g. "forcecopy" or "maybealias" or whatever) to allow their weird cases to remain standard compliant. Nobody loses.</div><div class=""><br class=""></div><div class="">People write C and C++ because they want the fastest possible compiled code — the standard should get out of the way wherever it is obstructing optimization.</div><div class=""><br class=""></div></div></div></blockquote></div><br class=""><div class="">Agreed, although this change seems to have the potential to break a very small subset of code out there in a very subtle manner, without an easy way to detect that. But maybe we can detect and warn about the most common/obvious violations at least and that is enough?</div><div class=""><br class=""></div><div class="">Cheers,</div><div class="">Florian</div></body></html>