mizvekov added inline comments.
================
Comment at: clang/lib/Sema/SemaStmt.cpp:3150-3153
+ // If we got a non-deduced auto ReturnType, we are in a dependent context and
+ // there is no point in allowing copy elision since we won't have it deduced
+ // by the point the VardDecl is instantiated, which is the last chance we
have
+ // of deciding if the candidate is really copy elisible.
----------------
mizvekov wrote:
> rsmith wrote:
> > How does this happen? Are there any cases where we could do NRVO or should
> > do an implicit move that are blocked by this?
> >
> > It seems to me that we should (nearly always) be able to work out whether
> > copy elision is possible here without knowing the deduced type:
> > -- if the return type is //cv// `auto` then it will always be deduced to
> > the type of the returned variable, so we can always perform copy elision
> > -- if the return type is `decltype(auto)`, then we can perform copy elision
> > if the expression is unparenthesized and otherwise cannot; we could perhaps
> > track whether the expression was parenthesized in `NRVOResult`, and can
> > conservatively disallow copy elision if we don't know (eg, from template
> > instantiation, where we're only looking at the variable and not the return
> > statements)
> > -- if the return type is anything else involving `auto`, it can't possibly
> > instantiate to a class type, so we'll never perform copy elision
> Yeah, what you suggested is what I tried on a previous patch in this DR, but
> then studying the NRVO tracker carefully I thought about this counter example:
> ```
> template<bool B> static auto bar() {
> {
> Foo foo;
> if constexpr(B)
> return foo;
> }
> {
> Bar bar;
> if constexpr(!B)
> return bar;
> }
> }
> ````
>
> Since we run the tracker before instantiation, we would see both return
> statements and mark both foo and bar as NRVO variables.
> Ofcourse in the B = false case, we would end up constructing a Foo in a Bar
> return slot....
>
> As a side note, It is actually funny that we currently perform this
> optimization (most likely accidentally):
> ```
> template<bool B> static Foo bar() {
> {
> Foo foo1;
> if constexpr(B)
> return foo1;
> }
> {
> Foo foo2;
> return foo2
> }
> }
> ```
> In the B = false case, we end up constructing foo1 in the return slot even
> though we actually never return it.
Compiler explorer link for the accidental optimization I am talking about:
https://godbolt.org/z/czdWodW87
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D99696/new/
https://reviews.llvm.org/D99696
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits