From 0045e0bc3ceacdd3e52d8f0a9162e92f1a5570db Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sat, 19 Jun 1999 11:11:43 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 9 +++++++ gcc/cp/decl.c | 24 +++++++++++++++++-- gcc/cp/error.c | 18 ++++++++++++++ .../g++.old-deja/g++.other/cleanup3.C | 17 +++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.other/cleanup3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b671eb324ad..eca957246c2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +1999-06-19 Mark Mitchell + + * 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 * init.c (expand_aggr_vbase_init): Add flag parameter. diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1fc452551dc..0a4d5396bda 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 ed316e1dafc..a79420ec778 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 00000000000..33d2c4d93ee --- /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 + +struct A { + virtual ~A(); + A(); +}; + +struct B: public A { + B(); +}; + +void f() +{ + static B t[2]; +}