decl.c (store_parm_decls): Generate cleanup code at semantic-analysis time.
authorMark Mitchell <mark@codesourcery.com>
Tue, 9 Nov 1999 07:40:14 +0000 (07:40 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 9 Nov 1999 07:40:14 +0000 (07:40 +0000)
* decl.c (store_parm_decls): Generate cleanup code at
semantic-analysis time.  Destroy objects in the correct order.

From-SVN: r30456

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/g++.old-deja/g++.other/dtor6.C [new file with mode: 0644]

index 59fc610f804cf051bbccff8cd6c1bd1e894005fe..24ef9a45aabb2e62b7bfc71d3041721b70cd2ec0 100644 (file)
@@ -1,3 +1,8 @@
+1999-11-08  Mark Mitchell  <mark@codesourcery.com>
+
+       * decl.c (store_parm_decls): Generate cleanup code at
+       semantic-analysis time.  Destroy objects in the correct order.
+
 1999-11-07  Mark Mitchell  <mark@codesourcery.com>
 
        * cp-tree.h (begin_new_placement): Remove.
index 71c30fa45dce2c73f4aaac169497cb2f822dcf42..e7a10b420807d340e04bbe0a90ddb2c56fe3d10b 100644 (file)
@@ -13163,26 +13163,26 @@ store_parm_decls ()
          next = TREE_CHAIN (parm);
          if (TREE_CODE (parm) == PARM_DECL)
            {
-             tree cleanup;
-             
+             tree type = TREE_TYPE (parm);
+
              if (doing_semantic_analysis_p ())
                {
+                 tree cleanup;
+             
                  if (DECL_NAME (parm) == NULL_TREE
-                     || TREE_CODE (TREE_TYPE (parm)) != VOID_TYPE)
+                     || TREE_CODE (parm) != VOID_TYPE)
                    pushdecl (parm);
                  else
                    cp_error ("parameter `%D' declared void", parm);
-               }
-
-             if (! building_stmt_tree ()
-                 && (cleanup = maybe_build_cleanup (parm), cleanup))
-               {
-                 expand_decl (parm);
-                 parms_have_cleanups = 1;
 
-                 /* Keep track of the cleanups.  */
-                 cleanups = tree_cons (parm, cleanup, cleanups);
+                 cleanup = maybe_build_cleanup (parm);
+                 
+                 if (cleanup)
+                   cleanups = tree_cons (parm, cleanup, cleanups);
                }
+             else if (type != error_mark_node
+                      && TYPE_NEEDS_DESTRUCTOR (type))
+               parms_have_cleanups = 1;
            }
          else
            {
@@ -13200,9 +13200,6 @@ store_parm_decls ()
             PARM_DECLs that were pushed into scope by the loop above.  */
          DECL_ARGUMENTS (fndecl) = getdecls ();
          storetags (chainon (parmtags, gettags ()));
-
-         /* We built up the cleanups in reversed order.  */
-         cleanups = nreverse (cleanups);
        }
     }
   else
@@ -13230,16 +13227,12 @@ store_parm_decls ()
   /* Now that we have initialized the parms, we can start their
      cleanups.  We cannot do this before, since expand_decl_cleanup
      should not be called before the parm can be used.  */
-  if (cleanups && !building_stmt_tree ())
-    while (cleanups)
-      {
-       if (! expand_decl_cleanup (TREE_PURPOSE (cleanups), 
-                                  TREE_VALUE (cleanups)))
-         cp_error ("parser lost in parsing declaration of `%D'",
-                   TREE_PURPOSE (cleanups));
-       
-       cleanups = TREE_CHAIN (cleanups);
-      }
+  while (cleanups)
+    {
+      finish_decl_cleanup (TREE_PURPOSE (cleanups), 
+                          TREE_VALUE (cleanups));
+      cleanups = TREE_CHAIN (cleanups);
+    }
 
   /* Create a binding contour which can be used to catch
      cleanup-generated temporaries.  Also, if the return value needs or
diff --git a/gcc/testsuite/g++.old-deja/g++.other/dtor6.C b/gcc/testsuite/g++.old-deja/g++.other/dtor6.C
new file mode 100644 (file)
index 0000000..6044849
--- /dev/null
@@ -0,0 +1,44 @@
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+extern "C" void abort ();
+
+int count;
+
+struct S
+{
+  S ();
+  S (const S&);
+  ~S ();
+
+  int i;
+};
+
+S::S ()
+{
+  i = count++;
+}
+
+S::S (const S&)
+{
+  i = count++;
+}
+
+S::~S ()
+{
+  if (--count != i)
+    abort ();
+}
+
+void f (S, S)
+{
+}
+
+int main ()
+{
+  {
+    S s;
+    f (s, s);
+  }
+  return count != 0;
+}
+