<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Nov 3, 2015 at 1:34 PM, Kim Gräsman <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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Tue, Nov 3, 2015 at 9:49 PM, Kim Gräsman <<a href="mailto:kim.grasman@gmail.com">kim.grasman@gmail.com</a>> wrote:<br>
><br>
> I'm experimenting with a patch to let users mark functions with an attribute<br>
><br>
> [[clang::requires_rvo]]<br>
> std::string f() {<br>
>     return std::string("Hello world");<br>
> }<br>
><br>
> and in the presence of this attribute, warn if (N)RVO didn't happen.<br>
> This would be useful to prevent small code changes from disabling RVO<br>
> in critical paths.<br>
><br>
> I have the attribute in place, and I've seen that I can check if it<br>
> exists with FunctionDecl::hasAttr. But finding where NRVO is actually<br>
> decided for a given function turns out to be more difficult...<br>
><br>
> SemaInit appears to do something for NRVO/copy elision more generally<br>
> when constructors are called. But it only marks the CXXConstructExpr<br>
> as elidable, as far as I can see, and I'm not sure if this is used to<br>
> effect RVO later (I found something in<br>
> CodeGenFunction::EmitCXXConstructExpr, but there seems to be more<br>
> playing into the decision of whether to construct at caller or not.<br>
><br>
> Also, I'm not sure if my terminology is right; I haven't found any<br>
> references to RVO-sans-the-N, is that refered to as copy elision? NRVO<br>
> only seems to address VarDecls and their lifetime.<br></span></blockquote><div><br></div><div>RVO is a special case of copy elision, where the elided copy is initializing the returned object.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
</span>I guess the more direct question is: is there a single place where I<br>
can detect if copy elision/NRVO/RVO has happened or will definitely<br>
happen for the return value of a function?<br></blockquote><div><br></div><div>Not really, no, our current model marks the places where it's permissible then leaves the details up to IR generation.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If not, I guess I'm thinking about the problem the wrong way; is there<br>
a more correct way to ask this question?</blockquote><div><br></div><div>P0135R0 was accepted by C++'s evolution working group in Kona, so RVO is likely to be guaranteed by the language semantics in C++17 onwards.</div><div><br></div><div>For NRVO, I think the best model would be an attribute on the variable:</div><div><br></div><div>  std::string f() {</div><div>    [[clang::returned]] std::string x = "Hello world";</div><div>    return x;</div><div>  }</div><div><br></div><div>... which would give an error if we can't apply NRVO to it.</div><div><br></div><div>(Also of note: clang's NRVO heuristic is currently quite weak, and improving it would seem like a good idea. In principle, we should be able to put a variable into the return slot in all cases where all return-statements within its scope return it.)</div></div></div></div>