summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/except.c91
-rw-r--r--gcc/except.h12
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
OpenPOWER on IntegriCloud