diff options
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/except.c | 91 | ||||
-rw-r--r-- | gcc/except.h | 12 |
3 files changed, 85 insertions, 31 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0576a018a01..040ec3a98a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +1999-11-25 Mark Mitchell <mark@codesourcery.com> + + * except.h (eh_status): Adjust documentation for x_protect_list. + (begin_protect_partials): New function. + * except.c (enqueue_eh_entry): Fix formatting. + (get_first_handler): Add consistency check. + (add_partial_entry): Adjust usage of protect_list. + (emit_cleanup_handler): Save and restore ehqueue. + (expand_start_all_catch): Add comment. + (begin_protect_partials): New function. + (end_protect_partials): Adjust usage of protect_list. + (init_eh_for_function): Use xcalloc. + 1999-11-25 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * c-common.c (check_format_info): Don't call a variadic function diff --git a/gcc/except.c b/gcc/except.c index 4b294769f12..a06c408c84a 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -643,13 +643,9 @@ enqueue_eh_entry (queue, entry) node->chain = NULL; if (queue->head == NULL) - { - queue->head = node; - } + queue->head = node; else - { - queue->tail->chain = node; - } + queue->tail->chain = node; queue->tail = node; } @@ -912,7 +908,10 @@ struct handler_info * get_first_handler (region) int region; { - return function_eh_regions[find_func_region (region)].handlers; + int r = find_func_region (region); + if (r == -1) + abort (); + return function_eh_regions[r].handlers; } /* Clean out the function_eh_region table and free all memory */ @@ -1097,7 +1096,15 @@ add_partial_entry (handler) with __terminate. */ handler = protect_with_terminate (handler); - protect_list = tree_cons (NULL_TREE, handler, protect_list); + /* For backwards compatibility, we allow callers to omit calls to + begin_protect_partials for the outermost region. So, we must + explicitly do so here. */ + if (!protect_list) + begin_protect_partials (); + + /* Add this entry to the front of the list. */ + TREE_VALUE (protect_list) + = tree_cons (NULL_TREE, handler, TREE_VALUE (protect_list)); pop_obstacks (); } @@ -1675,7 +1682,7 @@ expand_leftover_cleanups () entry; entry = dequeue_eh_entry (&ehqueue)) { - /* A leftover try bock. Shouldn't be one here. */ + /* A leftover try block. Shouldn't be one here. */ if (entry->finalization == integer_zero_node) abort (); @@ -1788,6 +1795,13 @@ emit_cleanup_handler (entry) { rtx prev; rtx handler_insns; + struct eh_queue q; + + /* Since the cleanup could itself contain try-catch blocks, we + squirrel away the current queue and replace it when we are done + with this function. */ + q = ehqueue; + ehqueue.head = ehqueue.tail = NULL; /* Put these handler instructions in a sequence. */ do_pending_stack_adjust (); @@ -1828,6 +1842,10 @@ emit_cleanup_handler (entry) emit_insns (handler_insns); catch_clauses = get_insns (); end_sequence (); + + /* Now we've left the handler. */ + expand_leftover_cleanups (); + ehqueue = q; } /* Generate RTL for the start of a group of catch clauses. @@ -1868,6 +1886,9 @@ expand_start_all_catch () the handlers in this handler-seq. */ start_sequence (); + /* Throw away entries in the queue that we won't need anymore. We + need entries for regions that have ended but to which there might + still be gotos pending. */ for (entry = dequeue_eh_entry (&ehqueue); entry->finalization != integer_zero_node; entry = dequeue_eh_entry (&ehqueue)) @@ -1989,17 +2010,44 @@ expand_rethrow (label) emit_jump (label); } +/* Begin a region that will contain entries created with + add_partial_entry. */ + +void +begin_protect_partials () +{ + /* Put the entry on the function obstack. */ + push_obstacks_nochange (); + resume_temporary_allocation (); + + /* Push room for a new list. */ + protect_list = tree_cons (NULL_TREE, NULL_TREE, protect_list); + + /* We're done with the function obstack now. */ + pop_obstacks (); +} + /* End all the pending exception regions on protect_list. The handlers will be emitted when expand_leftover_cleanups is invoked. */ void end_protect_partials () { - while (protect_list) - { - expand_eh_region_end (TREE_VALUE (protect_list)); - protect_list = TREE_CHAIN (protect_list); - } + tree t; + + /* For backwards compatibility, we allow callers to omit the call to + begin_protect_partials for the outermost region. So, + PROTECT_LIST may be NULL. */ + if (!protect_list) + return; + + /* End all the exception regions. */ + for (t = TREE_VALUE (protect_list); t; t = TREE_CHAIN (t)) + expand_eh_region_end (TREE_VALUE (t)); + + /* Pop the topmost entry. */ + protect_list = TREE_CHAIN (protect_list); + } /* Arrange for __terminate to be called if there is an unhandled throw @@ -2528,20 +2576,7 @@ void init_eh_for_function () { current_function->eh - = (struct eh_status *) xmalloc (sizeof (struct eh_status)); - - ehstack.top = 0; - catchstack.top = 0; - ehqueue.head = ehqueue.tail = 0; - catch_clauses = NULL_RTX; - false_label_stack = 0; - caught_return_label_stack = 0; - protect_list = NULL_TREE; - current_function_ehc = NULL_RTX; - eh_return_context = NULL_RTX; - eh_return_stack_adjust = NULL_RTX; - eh_return_handler = NULL_RTX; - eh_return_stub_label = NULL_RTX; + = (struct eh_status *) xcalloc (1, sizeof (struct eh_status)); } void diff --git a/gcc/except.h b/gcc/except.h index eafeaa942cd..6f15ff04a09 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -125,9 +125,10 @@ struct eh_status normal control flow out of a handler (instead of, say, returning to the caller of the current function or exiting the program). */ struct label_node *x_caught_return_label_stack; - /* A TREE_CHAINed list of handlers for regions that are not yet - closed. The TREE_VALUE of each entry contains the handler for the - corresponding entry on the ehstack. */ + /* A stack (TREE_LIST) of lists of handlers. The TREE_VALUE of each + node is itself a TREE_CHAINed list of handlers for regions that + are not yet closed. The TREE_VALUE of each entry contains the + handler for the corresponding entry on the ehstack. */ union tree_node *x_protect_list; /* The EH context. Nonzero if the function has already fetched a pointer to the EH context for exception handling. */ @@ -368,6 +369,11 @@ extern void expand_start_all_catch PROTO((void)); extern void expand_end_all_catch PROTO((void)); +/* Begin a region that will contain entries created with + add_partial_entry. */ + +extern void begin_protect_partials PROTO((void)); + #ifdef TREE_CODE /* Create a new exception region and add the handler for the region onto a list. These regions will be ended (and their handlers |