diff options
author | Mark Mitchell <mark@codesourcery.com> | 1999-11-09 07:40:14 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-11-09 07:40:14 +0000 |
commit | fe1b3b96aef55da97eda079a69381860ee764c3b (patch) | |
tree | f7fcdbac2e31f70e51aace4baffde1bae90e5d71 /gcc | |
parent | 312618c7d082170511d341cf08918e543490361b (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 43 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/dtor6.C | 44 |
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; +} + |