aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-11-09 07:40:14 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-11-09 07:40:14 +0000
commitfe1b3b96aef55da97eda079a69381860ee764c3b (patch)
treef7fcdbac2e31f70e51aace4baffde1bae90e5d71 /gcc
parent312618c7d082170511d341cf08918e543490361b (diff)
downloadgcc-fe1b3b96aef55da97eda079a69381860ee764c3b.zip
gcc-fe1b3b96aef55da97eda079a69381860ee764c3b.tar.gz
gcc-fe1b3b96aef55da97eda079a69381860ee764c3b.tar.bz2
decl.c (store_parm_decls): Generate cleanup code at semantic-analysis time.
* decl.c (store_parm_decls): Generate cleanup code at semantic-analysis time. Destroy objects in the correct order. From-SVN: r30456
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl.c43
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/dtor6.C44
3 files changed, 67 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 59fc610..24ef9a4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 71c30fa..e7a10b4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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
index 0000000..6044849
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/dtor6.C
@@ -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;
+}
+