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
This commit is contained in:
Mark Mitchell 1999-06-19 11:11:43 +00:00 committed by Mark Mitchell
parent 61571dfc4a
commit 0045e0bc3c
4 changed files with 66 additions and 2 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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];
}