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
This commit is contained in:
parent
f1b62339fa
commit
35e939ae1c
3 changed files with 45 additions and 3 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
26
gcc/testsuite/g++.dg/opt/nrv6.C
Normal file
26
gcc/testsuite/g++.dg/opt/nrv6.C
Normal file
|
@ -0,0 +1,26 @@
|
|||
// PR c++/9993
|
||||
// Bug: We were failing to destroy b.
|
||||
|
||||
// { dg-do run }
|
||||
|
||||
int c, d;
|
||||
|
||||
struct Object {
|
||||
Object() { ++c; }
|
||||
Object(const Object&) { ++c; }
|
||||
~Object() { ++d; }
|
||||
};
|
||||
|
||||
Object function() {
|
||||
int i = 0;
|
||||
do {
|
||||
Object b;
|
||||
if (i++ == 2)
|
||||
return b;
|
||||
} while (1);
|
||||
}
|
||||
|
||||
int main() {
|
||||
function();
|
||||
return c != d;
|
||||
}
|
Loading…
Add table
Reference in a new issue