From: Mike Stump Date: Thu, 7 Jul 1994 03:08:23 +0000 (+0000) Subject: expr.c (expand_expr, [...]): All cleanups have to be protected by interim exception... X-Git-Tag: misc/cutover-egcs-0~6277 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=61d6b1cca163eda08e3b93f3032cc53d3f9b2de8;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/expr.c b/gcc/expr.c index a2b24c4b051e..b9cd009f7af8 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 c93c9badc804..5c472e709540 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 ad440ae6023a..d4b1043e0d02 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;