aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2003-03-17 10:45:29 -0500
committerJason Merrill <jason@gcc.gnu.org>2003-03-17 10:45:29 -0500
commit35e939ae1c46ee21ad069d23f77c5e359c7c8ad1 (patch)
tree5e415b4ac71c0adab0b0fb00508728fe2bc54f8f /gcc/cp
parentf1b62339fa1f8b2021750ffe334adc3da73e8d02 (diff)
downloadgcc-35e939ae1c46ee21ad069d23f77c5e359c7c8ad1.zip
gcc-35e939ae1c46ee21ad069d23f77c5e359c7c8ad1.tar.gz
gcc-35e939ae1c46ee21ad069d23f77c5e359c7c8ad1.tar.bz2
re PR c++/9993 (destructor not called for local object created within and returned from infinite loop)
PR c++/9993 * decl.c (finish_function): Only allow the NRVO to use variables declared at function scope. From-SVN: r64488
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c16
2 files changed, 19 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c0a968f..2439edd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2003-03-16 Jason Merrill <jason@redhat.com>
+
+ PR c++/9993
+ * decl.c (finish_function): Only allow the NRVO to use variables
+ declared at function scope.
+
2003-03-17 Andreas Jaeger <aj@suse.de>
* Make-lang.in (cp/TAGS): Remove.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6d68251..e00a5f3 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -14092,11 +14092,21 @@ finish_function (int flags)
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. */
+ tree outer;
+
if (r != error_mark_node
- && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
+ /* 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);