This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for c++/9993
- From: Jason Merrill <jason at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 17 Mar 2003 10:38:36 -0500
- Subject: C++ PATCH for c++/9993
In g++.dg/opt/nrv6.C, we were selecting for the named return value a
variable declared inside a loop, and then nullifying the cleanups for that
destructor on the invalid assumption that the NRV is only destroyed on
return. This patch narrows the optimization to only accept variables
declared at function scope, for which that assumption is valid.
Tested i686-pc-linux-gnu, applied to 3.2, 3.3 and trunk.
2003-03-16 Jason Merrill <jason at redhat dot com>
PR c++/9993
* decl.c (finish_function): Only allow the NRVO to use variables
declared at function scope.
*** decl.c.~1~ 2003-03-16 01:05:02.000000000 -0500
--- decl.c 2003-03-17 01:11:08.000000000 -0500
*************** finish_function (int flags)
*** 14089,14099 ****
if (current_function_return_value)
{
tree r = current_function_return_value;
! /* This is only worth doing for fns that return in memory--and
! simpler, since we don't have to worry about promoted modes. */
if (r != error_mark_node
! && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
{
DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fndecl));
walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
nullify_returns_r, r);
--- 14089,14109 ----
if (current_function_return_value)
{
tree r = current_function_return_value;
! tree outer;
!
if (r != error_mark_node
! /* This is only worth doing for fns that return in memory--and
! simpler, since we don't have to worry about promoted modes. */
! && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)))
! /* Only allow this for variables declared in the outer scope of
! the function so we know that their lifetime always ends with a
! return; see g++.dg/opt/nrv6.C. We could be more flexible if
! we were to do this optimization in tree-ssa. */
! /* Skip the artificial function body block. */
! && (outer = BLOCK_SUBBLOCKS (BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl))),
! chain_member (r, BLOCK_VARS (outer))))
{
+
DECL_ALIGN (r) = DECL_ALIGN (DECL_RESULT (fndecl));
walk_tree_without_duplicates (&DECL_SAVED_TREE (fndecl),
nullify_returns_r, r);