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:
parent
61571dfc4a
commit
0045e0bc3c
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
17
gcc/testsuite/g++.old-deja/g++.other/cleanup3.C
Normal file
17
gcc/testsuite/g++.old-deja/g++.other/cleanup3.C
Normal 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];
|
||||
}
|
Loading…
Reference in New Issue
Block a user