diff options
author | Mike Stump <mrs@gcc.gnu.org> | 1994-07-07 03:08:23 +0000 |
---|---|---|
committer | Mike Stump <mrs@gcc.gnu.org> | 1994-07-07 03:08:23 +0000 |
commit | 61d6b1cca163eda08e3b93f3032cc53d3f9b2de8 (patch) | |
tree | 1c752111fb50bcfb3bc6b07878787a588a0289ba /gcc | |
parent | 6bc55d0587fca7984aa2aca637803b42126a381f (diff) | |
download | gcc-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.c | 15 | ||||
-rw-r--r-- | gcc/stmt.c | 5 | ||||
-rw-r--r-- | gcc/toplev.c | 16 |
3 files changed, 35 insertions, 1 deletions
@@ -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 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; |