diff options
author | Mark Mitchell <mark@codesourcery.com> | 1999-06-19 11:11:43 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 1999-06-19 11:11:43 +0000 |
commit | 0045e0bc3ceacdd3e52d8f0a9162e92f1a5570db (patch) | |
tree | 3f68877ca60ca264dadc0597d76ec96371959917 | |
parent | 61571dfc4a69d6be22522fe8ee303946d516dd9f (diff) | |
download | gcc-0045e0bc3ceacdd3e52d8f0a9162e92f1a5570db.zip gcc-0045e0bc3ceacdd3e52d8f0a9162e92f1a5570db.tar.gz gcc-0045e0bc3ceacdd3e52d8f0a9162e92f1a5570db.tar.bz2 |
decl.c (expand_static_init): When building an anonymous function for use with atexit...
* decl.c (expand_static_init): When building an anonymous function
for use with atexit, compute its body before and after entering
the function.
* error.c (dump_expr): Handle BIND_EXPR, LOOP_EXPR, and
EXIT_EXPR.
From-SVN: r27612
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/decl.c | 24 | ||||
-rw-r--r-- | gcc/cp/error.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/cleanup3.C | 17 |
4 files changed, 66 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b671eb3..eca9572 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +1999-06-19 Mark Mitchell <mark@codesourcery.com> + + * decl.c (expand_static_init): When building an anonymous function + for use with atexit, compute its body before and after entering + the function. + + * error.c (dump_expr): Handle BIND_EXPR, LOOP_EXPR, and + EXIT_EXPR. + 1999-06-18 Mark Mitchell <mark@codesourcery.com> * init.c (expand_aggr_vbase_init): Add flag parameter. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1fc4525..0a4d539 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8509,6 +8509,8 @@ expand_static_init (decl, init) { tree cleanup, fcall; static tree Atexit = 0; + int saved_flag_access_control; + if (Atexit == 0) { tree atexit_fndecl, PFV, pfvlist; @@ -8540,13 +8542,31 @@ expand_static_init (decl, init) so that any access checks will be done relative to the current scope, rather than the scope of the anonymous function. */ - fcall = build_cleanup (decl); + build_cleanup (decl); + + /* Now start the function. */ cleanup = start_anon_func (); + + /* Now, recompute the cleanup. It may contain SAVE_EXPRs + that refer to the original function, rather than the + anonymous one. That will make the back-end think that + nested functions are in use, which causes confusion. */ + saved_flag_access_control = flag_access_control; + flag_access_control = 0; + fcall = build_cleanup (decl); + flag_access_control = saved_flag_access_control; + + /* Finish off the function. */ expand_expr_stmt (fcall); end_anon_func (); + + /* Call atexit with the cleanup function. */ mark_addressable (cleanup); cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); - fcall = build_function_call (Atexit, expr_tree_cons (NULL_TREE, cleanup, NULL_TREE)); + fcall = build_function_call (Atexit, + expr_tree_cons (NULL_TREE, + cleanup, + NULL_TREE)); expand_expr_stmt (fcall); } diff --git a/gcc/cp/error.c b/gcc/cp/error.c index ed316e1..a79420e 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1779,6 +1779,24 @@ dump_expr (t, nop) dump_decl (t, 0); break; + case BIND_EXPR: + OB_PUTS ("{ "); + dump_expr (TREE_OPERAND (t, 1), nop); + OB_PUTS ("} "); + break; + + case LOOP_EXPR: + OB_PUTS ("while (1) { "); + dump_expr (TREE_OPERAND (t, 0), nop); + OB_PUTS ("} "); + break; + + case EXIT_EXPR: + OB_PUTS ("if ("); + dump_expr (TREE_OPERAND (t, 0), nop); + OB_PUTS (") break; "); + break; + case TREE_LIST: if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL) { diff --git a/gcc/testsuite/g++.old-deja/g++.other/cleanup3.C b/gcc/testsuite/g++.old-deja/g++.other/cleanup3.C new file mode 100644 index 0000000..33d2c4d --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/cleanup3.C @@ -0,0 +1,17 @@ +// Build don't link: +// Special g++ Options: -fno-vtable-thunks +// Origin: Marc Espie <espie@tetto.liafa.jussieu.fr> + +struct A { + virtual ~A(); + A(); +}; + +struct B: public A { + B(); +}; + +void f() +{ + static B t[2]; +} |