mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-19 01:50:34 +08:00
c++: NRV in lambda in template [PR91217]
tsubst_lambda_expr was producing a function with two blocks that claimed to be the outermost block in the function body, one from the call to start_lambda_function in tsubst_lambda_expr, and one from tsubsting the block added by start_lambda_function when we first parsed the lambda. This messed with the named return value optimization, which only works for variables in the outermost block. gcc/cp/ChangeLog: PR c++/91217 * pt.c (tsubst_lambda_expr): Skip the body block from DECL_SAVED_TREE. gcc/testsuite/ChangeLog: PR c++/91217 * g++.dg/opt/nrv20.C: New test.
This commit is contained in:
parent
7c3ba2145c
commit
04771106cd
@ -19433,8 +19433,13 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
the purposes of template argument deduction. */
|
||||
complain = tf_warning_or_error;
|
||||
|
||||
tsubst_expr (DECL_SAVED_TREE (oldfn), args, complain, r,
|
||||
/*constexpr*/false);
|
||||
tree saved = DECL_SAVED_TREE (oldfn);
|
||||
if (TREE_CODE (saved) == BIND_EXPR && BIND_EXPR_BODY_BLOCK (saved))
|
||||
/* We already have a body block from start_lambda_function, we don't
|
||||
need another to confuse NRV (91217). */
|
||||
saved = BIND_EXPR_BODY (saved);
|
||||
|
||||
tsubst_expr (saved, args, complain, r, /*constexpr*/false);
|
||||
|
||||
finish_lambda_function (body);
|
||||
|
||||
|
20
gcc/testsuite/g++.dg/opt/nrv20.C
Normal file
20
gcc/testsuite/g++.dg/opt/nrv20.C
Normal file
@ -0,0 +1,20 @@
|
||||
// PR c++/91217
|
||||
// { dg-do compile { target c++11 } }
|
||||
// { dg-additional-options -fdump-tree-gimple }
|
||||
// { dg-final { scan-tree-dump-not "<retval> = a" "gimple" } }
|
||||
|
||||
struct A
|
||||
{
|
||||
int ar[42];
|
||||
};
|
||||
|
||||
template <class T>
|
||||
A f()
|
||||
{
|
||||
return [] { A a; return a; }();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
f<int>();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user