From 42f02385bdfb21849e984584082047881f53d8c9 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 4 Oct 2007 13:58:07 -0400 Subject: re PR c++/20416 (Incorrect lifetime for temporary with static const reference) PR c++/20416 * call.c (initialize_reference): Handle local static reference temps properly. From-SVN: r129020 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/call.c | 6 +++++- gcc/testsuite/g++.dg/init/ref15.C | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/init/ref15.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0cec087..240990e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2007-10-04 Jason Merrill + + PR c++/20416 + * call.c (initialize_reference): Handle local static reference + temps properly. + 2007-10-03 Jason Merrill PR c++/32470 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 645eeb2..cf3aea7 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6824,7 +6824,11 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) if (at_function_scope_p ()) { add_decl_expr (var); - *cleanup = cxx_maybe_build_cleanup (var); + + if (TREE_STATIC (var)) + init = add_stmt_to_compound (init, register_dtor_fn (var)); + else + *cleanup = cxx_maybe_build_cleanup (var); /* We must be careful to destroy the temporary only after its initialization has taken place. If the diff --git a/gcc/testsuite/g++.dg/init/ref15.C b/gcc/testsuite/g++.dg/init/ref15.C new file mode 100644 index 0000000..d3a9422 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/ref15.C @@ -0,0 +1,32 @@ +// PR c++/20416. We correctly constructed the temporary S in foo(), +// but incorrectly destroyed it every time foo() was called. +// { dg-do run } +extern "C" void abort (void); +extern "C" void _exit (int); + +int c, exiting; +struct S { + S() { ++c; } + S(const S &) { ++c; } + ~S() + { + if (!exiting) abort (); + _exit (0); + } +}; +void +foo (void) +{ + static const S &s = S(); +} +int main () +{ + if (c != 0) + abort (); + foo (); + foo (); + if (c != 1) + abort (); + exiting = 1; + return 1; +} -- cgit v1.1