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. ---------------- 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. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D99696/new/ https://reviews.llvm.org/D99696 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits