Commit 61d6b1cc by Mike Stump

expr.c (expand_expr, [...]): All cleanups have to be protected by interim exception handling code.

        * expr.c (expand_expr, defer_cleanups_to, expand_cleanups_to): All
        cleanups have to be protected by interim exception handling code.
        * stmt.c (expand_decl_cleanup, expand_cleanups): Ditto.
        * toplev.c (interim_eh_hook): Hook for interim exception handling.
        * toplev.c (interim_eh): Default implementation for exception
        handling that does nothing.
        * toplev.c (main): Set default for interim_eh_hook.

From-SVN: r7666
parent 6bc55d05
......@@ -180,6 +180,7 @@ static void do_jump_for_compare PROTO((rtx, rtx, rtx));
static rtx compare PROTO((tree, enum rtx_code, enum rtx_code));
static rtx do_store_flag PROTO((tree, rtx, enum machine_mode, int));
static tree defer_cleanups_to PROTO((tree));
extern void (*interim_eh_hook) PROTO((tree));
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
......@@ -4616,6 +4617,7 @@ expand_expr (exp, target, tmode, modifier)
= tree_cons (NULL_TREE, TREE_OPERAND (exp, 2), cleanups_this_call);
/* That's it for this cleanup. */
TREE_OPERAND (exp, 2) = 0;
(*interim_eh_hook) (NULL_TREE);
}
return RTL_EXPR_RTL (exp);
......@@ -5657,12 +5659,14 @@ expand_expr (exp, target, tmode, modifier)
/* Now add in the conditionalized cleanups. */
cleanups_this_call
= tree_cons (NULL_TREE, new_cleanups, cleanups_this_call);
(*interim_eh_hook) (NULL_TREE);
}
return temp;
}
case TARGET_EXPR:
{
int need_exception_region = 0;
/* Something needs to be initialized, but we didn't know
where that thing was when building the tree. For example,
it could be the return value of a function, or a parameter
......@@ -5674,6 +5678,7 @@ expand_expr (exp, target, tmode, modifier)
tree slot = TREE_OPERAND (exp, 0);
tree exp1;
rtx temp;
if (TREE_CODE (slot) != VAR_DECL)
abort ();
......@@ -5709,6 +5714,7 @@ expand_expr (exp, target, tmode, modifier)
cleanups_this_call = tree_cons (NULL_TREE,
TREE_OPERAND (exp, 2),
cleanups_this_call);
need_exception_region = 1;
}
}
}
......@@ -5738,7 +5744,12 @@ expand_expr (exp, target, tmode, modifier)
/* Mark it as expanded. */
TREE_OPERAND (exp, 1) = NULL_TREE;
return expand_expr (exp1, target, tmode, modifier);
temp = expand_expr (exp1, target, tmode, modifier);
if (need_exception_region)
(*interim_eh_hook) (NULL_TREE);
return temp;
}
case INIT_EXPR:
......@@ -8279,6 +8290,7 @@ defer_cleanups_to (old_cleanups)
while (cleanups_this_call != old_cleanups)
{
(*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
cleanups_this_call = TREE_CHAIN (cleanups_this_call);
}
......@@ -8314,6 +8326,7 @@ expand_cleanups_to (old_cleanups)
{
while (cleanups_this_call != old_cleanups)
{
(*interim_eh_hook) (TREE_VALUE (cleanups_this_call));
expand_expr (TREE_VALUE (cleanups_this_call), const0_rtx, VOIDmode, 0);
cleanups_this_call = TREE_CHAIN (cleanups_this_call);
}
......
......@@ -137,6 +137,8 @@ extern tree rtl_expr_chain;
cleanup list whenever an empty list is required. */
static tree empty_cleanup_list;
#endif
extern void (*interim_eh_hook) PROTO((tree));
/* Functions and data structures for expanding case statements. */
......@@ -3483,6 +3485,7 @@ expand_decl_cleanup (decl, cleanup)
= temp_tree_cons (decl, cleanup, thisblock->data.block.cleanups);
/* If this block has a cleanup, it belongs in stack_block_stack. */
stack_block_stack = thisblock;
(*interim_eh_hook) (NULL_TREE);
}
return 1;
}
......@@ -3562,6 +3565,8 @@ expand_cleanups (list, dont_do)
expand_cleanups (TREE_VALUE (tail), dont_do);
else
{
(*interim_eh_hook) (TREE_VALUE (tail));
/* Cleanups may be run multiple times. For example,
when exiting a binding contour, we expand the
cleanups associated with that contour. When a goto
......
......@@ -254,6 +254,12 @@ struct rtx_def *(*lang_expand_expr) ();
void (*incomplete_decl_finalize_hook) () = 0;
/* Pointer to function for interim exception handling implementation.
This interface will change, and it is only here until a better interface
replaces it. */
void (*interim_eh_hook) PROTO((tree));
/* Nonzero if generating code to do profiling. */
int profile_flag = 0;
......@@ -996,6 +1002,15 @@ decl_name (decl, kind)
{
return IDENTIFIER_POINTER (DECL_NAME (decl));
}
/* This is the default interim_eh_hook function. */
void
interim_eh (finalization)
tree finalization;
{
/* Don't do anything by default. */
}
static int need_error_newline;
......@@ -3341,6 +3356,7 @@ main (argc, argv, envp)
decl_printable_name = decl_name;
lang_expand_expr = (struct rtx_def *(*)()) do_abort;
interim_eh_hook = interim_eh;
/* Initialize whether `char' is signed. */
flag_signed_char = DEFAULT_SIGNED_CHAR;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment