aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1994-07-07 03:08:23 +0000
committerMike Stump <mrs@gcc.gnu.org>1994-07-07 03:08:23 +0000
commit61d6b1cca163eda08e3b93f3032cc53d3f9b2de8 (patch)
tree1c752111fb50bcfb3bc6b07878787a588a0289ba /gcc
parent6bc55d0587fca7984aa2aca637803b42126a381f (diff)
downloadgcc-61d6b1cca163eda08e3b93f3032cc53d3f9b2de8.zip
gcc-61d6b1cca163eda08e3b93f3032cc53d3f9b2de8.tar.gz
gcc-61d6b1cca163eda08e3b93f3032cc53d3f9b2de8.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/expr.c15
-rw-r--r--gcc/stmt.c5
-rw-r--r--gcc/toplev.c16
3 files changed, 35 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index a2b24c4..b9cd009 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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);
}
diff --git a/gcc/stmt.c b/gcc/stmt.c
index c93c9ba..5c472e7 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -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
diff --git a/gcc/toplev.c b/gcc/toplev.c
index ad440ae..d4b1043 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -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;