OSDN Git Service

PR c++/20416
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 4 Oct 2007 17:58:07 +0000 (17:58 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 4 Oct 2007 17:58:07 +0000 (17:58 +0000)
        * call.c (initialize_reference): Handle local static reference
        temps properly.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@129020 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/g++.dg/init/ref15.C [new file with mode: 0644]

index 0cec087..240990e 100644 (file)
@@ -1,3 +1,9 @@
+2007-10-04  Jason Merrill  <jason@redhat.com>
+
+       PR c++/20416
+       * call.c (initialize_reference): Handle local static reference
+       temps properly.
+
 2007-10-03  Jason Merrill  <jason@redhat.com>
 
        PR c++/32470
index 645eeb2..cf3aea7 100644 (file)
@@ -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 (file)
index 0000000..d3a9422
--- /dev/null
@@ -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;
+}