Izaron added a comment. There is a nice proposal (P2025) Guaranteed copy elision for return variables <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2025r2.html> by **Anton Zhilin**. The poll on the proposal showed that its ideas are very welcome: link to cplusplus/papers github <https://github.com/cplusplus/papers/issues/756#issuecomment-845364557>. Although the proposal is not yet accepted into the Standard in its current wording, some ideas are still good and can be implemented "in advance".
> This proposal aims to provide guaranteed copy elision for common cases of > local variables being returned from a function, a.k.a. "guaranteed NRVO". С++ сompiler implementations determine by their own rules whether there will be a NRVO (since it is not a required optimization). The proposal contains a collection of common cases of local variables being returned where copy elision is safe and makes senses and therefore is desirable to do. The main requirement (omitting details for language-lawyers) is that: > Copy elision is guaranteed for return x; if every return "seen" by x is > return x; "seen by `x`" means here "all non-discarded return statements in `x`'s potential scope". There are more details in the proposal. The collection of common cases contains 20 examples: §4.1. Examples <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2025r2.html#examples>. Here is the current status of these examples: - [OK] 13 out of 20 examples are working in Clang as expected. - [FAIL] 13th example: should be considered separately (as part of fixing consteval code) - [FAIL] 14th example: should be considered separately (as I haven't looked yet how `CXXCatchStmt` works). - [FAIL] 18th example: is unfixable now because of Clang's architecture: my comment on the issue <https://github.com/llvm/llvm-project/issues/50297#issuecomment-1033059593>. - **[OK with the patch]** 7th, 8th, 11th, 15th example: are working with this patch. In order to make the last group of 4 examples working, there is a need to rewrite the logic for calculating the NRVO candidate. The `clang::Scope` class has methods `void AddDecl(Decl *D)`, `void addNRVOCandidate(VarDecl *VD)`, `void setNoNRVO()`, that are called in the order of the scope's parsing. - `void AddDecl(Decl *D)` is called when there is a new `Decl *D` in the scope. The `D`'s potential scope starts now. - `void addNRVOCandidate(VarDecl *VD)` is called when there is a `return <named-variable>` in the scope or when a children scope has successfully calculated its single NRVO candidate. - `void setNoNRVO()` is called when there is a `return <not-a-named-var>` in the scope or when a children scope is telling us to drop our NRVO candidates (nevertheless, the children scope now can still succesfully calculated the NRVO candidate). We need to have a set of "unspoiled variables" to find the NRVO candidate effectively (yeah, introducing some made up terminology...) A variable is "unspoiled" if it is not forbidden to be the NRVO candidate yet. An `AddDecl` call adds the variable to this set. An `addNRVOCandidate` call "spoils" every variable except `VD`. A `setNoNRVO` "spoils" every variable. Only an "unspoiled variable" may be the NRVO candidate. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D119792/new/ https://reviews.llvm.org/D119792 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits