This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

EH PATCH: Don't push a binding level for an EH region


The old EH code used binding levels for EH regions in order to control
variables for the sjlj implementation and to catch jumps into try blocks.
This was implemented poorly; we would push a level for an EH region in a
structured way, then pop it either in the usual structured way, or
arbitrarily as part of trying to pop a non-EH region.  As one might
imagine, this can lead to too many things being popped if we're not very
careful.

The sjlj variables don't exist in the new implementation, and bad jumps
are now caught in the frontend, so we can do away with this kludge.

Fixes several libstdc++ testsuite failures.  Tested i686-pc-linux-gnu.

2001-04-28  Jason Merrill  <jason_merrill@redhat.com>

	* except.c (expand_eh_region_start): Don't start a new block.
	(expand_eh_region_end): Don't end a block.
	* stmt.c (expand_end_bindings): Don't end EH blocks.
	(expand_decl_cleanup): Starting an EH region won't change the block.
	(mark_block_as_eh_region, mark_block_as_not_eh_region): Lose.
	(is_eh_region): Lose.
	* tree.h: Adjust.

Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.154
diff -c -p -r1.154 except.c
*** except.c	2001/04/26 23:32:49	1.154
--- except.c	2001/04/27 23:23:58
*************** expand_eh_region_start ()
*** 643,659 ****
    if (! doing_eh (0))
      return;
  
-   /* We need a new block to record the start and end of the dynamic
-      handler chain.  We also want to prevent jumping into a try block.  */
-   expand_start_bindings (2);
- 
-   /* But we don't need or want a new temporary level.  */
-   pop_temp_slots ();
- 
-   /* Mark this block as created by expand_eh_region_start.  This is so
-      that we can pop the block with expand_end_bindings automatically.  */
-   mark_block_as_eh_region ();
- 
    /* Insert a new blank region as a leaf in the tree.  */
    new_region = (struct eh_region *) xcalloc (1, sizeof (*new_region));
    cur_region = cfun->eh->cur_region;
--- 643,648 ----
*************** expand_eh_region_end ()
*** 691,710 ****
    /* Pop.  */
    cfun->eh->cur_region = cur_region->outer;
  
-   /* If we have already started ending the bindings, don't recurse.  */
-   if (is_eh_region ())
-     {
-       /* Because we don't need or want a new temporary level and
- 	 because we didn't create one in expand_eh_region_start,
- 	 create a fake one now to avoid removing one in
- 	 expand_end_bindings.  */
-       push_temp_slots ();
- 
-       mark_block_as_not_eh_region ();
- 
-       expand_end_bindings (NULL_TREE, 0, 0);
-     }
- 
    return cur_region;
  }
  
--- 680,685 ----
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.192
diff -c -p -r1.192 stmt.c
*** stmt.c	2001/04/12 03:41:36	1.192
--- stmt.c	2001/04/27 23:24:03
*************** is_body_block (stmt)
*** 3380,3407 ****
    return 0;
  }
  
- /* Mark top block of block_stack as an implicit binding for an
-    exception region.  This is used to prevent infinite recursion when
-    ending a binding with expand_end_bindings.  It is only ever called
-    by expand_eh_region_start, as that it the only way to create a
-    block stack for a exception region.  */
- 
- void
- mark_block_as_eh_region ()
- {
-   block_stack->data.block.exception_region = 1;
-   if (block_stack->next
-       && block_stack->next->data.block.conditional_code)
-     {
-       block_stack->data.block.conditional_code
- 	= block_stack->next->data.block.conditional_code;
-       block_stack->data.block.last_unconditional_cleanup
- 	= block_stack->next->data.block.last_unconditional_cleanup;
-       block_stack->data.block.cleanup_ptr
- 	= block_stack->next->data.block.cleanup_ptr;
-     }
- }
- 
  /* True if we are currently emitting insns in an area of output code
     that is controlled by a conditional expression.  This is used by
     the cleanup handling code to generate conditional cleanup actions.  */
--- 3380,3385 ----
*************** conditional_context ()
*** 3412,3440 ****
    return block_stack && block_stack->data.block.conditional_code;
  }
  
- /* Mark top block of block_stack as not for an implicit binding for an
-    exception region.  This is only ever done by expand_eh_region_end
-    to let expand_end_bindings know that it is being called explicitly
-    to end the binding layer for just the binding layer associated with
-    the exception region, otherwise expand_end_bindings would try and
-    end all implicit binding layers for exceptions regions, and then
-    one normal binding layer.  */
- 
- void
- mark_block_as_not_eh_region ()
- {
-   block_stack->data.block.exception_region = 0;
- }
- 
- /* True if the top block of block_stack was marked as for an exception
-    region by mark_block_as_eh_region.  */
- 
- int
- is_eh_region ()
- {
-   return cfun && block_stack && block_stack->data.block.exception_region;
- }
- 
  /* Emit a handler label for a nonlocal goto handler.
     Also emit code to store the handler label in SLOT before BEFORE_INSN.  */
  
--- 3390,3395 ----
*************** expand_end_bindings (vars, mark_ends, do
*** 3637,3663 ****
       int mark_ends;
       int dont_jump_in;
  {
!   register struct nesting *thisblock;
! 
!   while (block_stack->data.block.exception_region)
!     {
!       /* Because we don't need or want a new temporary level and
! 	 because we didn't create one in expand_eh_region_start,
! 	 create a fake one now to avoid removing one in
! 	 expand_end_bindings.  */
!       push_temp_slots ();
! 
!       block_stack->data.block.exception_region = 0;
  
-       expand_end_bindings (NULL_TREE, 0, 0);
-     }
- 
-   /* Since expand_eh_region_start does an expand_start_bindings, we
-      have to first end all the bindings that were created by
-      expand_eh_region_start.  */
- 
-   thisblock = block_stack;
- 
    /* If any of the variables in this scope were not used, warn the
       user.  */
    warn_about_unused_variables (vars);
--- 3592,3599 ----
       int mark_ends;
       int dont_jump_in;
  {
!   register struct nesting *thisblock = block_stack;
  
    /* If any of the variables in this scope were not used, warn the
       user.  */
    warn_about_unused_variables (vars);
*************** expand_decl_cleanup (decl, cleanup)
*** 4076,4084 ****
  	TREE_ADDRESSABLE (t) = 1;
        else
  	expand_eh_region_start ();
- 
-       /* If that started a new EH region, we're in a new block.  */
-       thisblock = block_stack;
  
        if (cond_context)
  	{
--- 4012,4017 ----
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.236
diff -c -p -r1.236 tree.h
*** tree.h	2001/04/13 21:10:15	1.236
--- tree.h	2001/04/27 23:24:04
*************** extern void start_cleanup_deferral		PARA
*** 2552,2564 ****
  extern void end_cleanup_deferral		PARAMS ((void));
  extern int is_body_block			PARAMS ((tree));
  
- extern void mark_block_as_eh_region		PARAMS ((void));
- extern void mark_block_as_not_eh_region		PARAMS ((void));
- extern int is_eh_region				PARAMS ((void));
  extern int conditional_context			PARAMS ((void));
  extern tree last_cleanup_this_contour		PARAMS ((void));
- extern int expand_dhc_cleanup			PARAMS ((tree));
- extern int expand_dcc_cleanup			PARAMS ((tree));
  extern void expand_start_case			PARAMS ((int, tree, tree,
  						       const char *));
  extern void expand_end_case			PARAMS ((tree));
--- 2552,2559 ----

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]