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]
Other format: [Raw text]

[tree-ssa] PATCH to compute_reachable_eh


compute_reachable_eh was failing to handle the case of a try block with
multiple catch blocks.  Fixing this removes several of the libstdc++
execute failures.

However, representing that case using a COMPOUND_EXPR is a bit ambiguous.
Perhaps we should chain CATCH_EXPRs using TREE_CHAIN instead?  Thoughts,
anyone?

Tested i686-pc-linux-gnu, applied to tree-ssa branch.

2003-05-21  Jason Merrill  <jason@redhat.com>

	* tree-cfg.c (compute_reachable_eh): Handle multiple CATCH_EXPRs.

*** tree-cfg.c.~1~	2003-05-20 16:40:46.000000000 -0400
--- tree-cfg.c	2003-05-21 22:39:00.000000000 -0400
*************** compute_reachable_eh (tree stmt)
*** 4160,4165 ****
--- 4160,4166 ----
    tree reachable_handlers = NULL_TREE;
    tree types_caught = NULL_TREE;
    int skip_cleanups = 0;
+   tree_stmt_iterator si;
  
    /* EH_STACK contains all the exception handlers which enclose
       this statement.
*************** compute_reachable_eh (tree stmt)
*** 4173,4217 ****
        tree handler = VARRAY_TREE (eh_stack, i);
        tree tp_node;
  
!       if (TREE_CODE (handler) == CATCH_EXPR)
  	{
! 	  tree types = CATCH_TYPES (handler);
! 
! 	  /* This is a try/catch construct.  If it has no
! 	     CATCH_TYPES, then it catches all types and we
! 	     can stop our search early.  */
! 	  if (types == NULL_TREE)
  	    {
! 	      reachable_handlers = tree_cons (void_type_node,
! 					      VARRAY_TREE (eh_stack, i),
! 					      reachable_handlers);
! 	      break;
! 	    }
  
! 	  /* If TYPES is not a list, make it a list to
! 	     simplify handling below.  */
! 	  if (TREE_CODE (types) != TREE_LIST)
! 	    types = tree_cons (NULL_TREE, types, NULL_TREE);
! 
! 	  /* See if the CATCH_TYPES specifies any types that have
! 	     not already been handled.  If so, add those types to
! 	     the types we handle and add this handler to the list
! 	     of reachable handlers.  */
! 	  for (tp_node = types; tp_node; tp_node = TREE_CHAIN (tp_node))
! 	    {
! 	      tree type = TREE_VALUE (tp_node);
  
! 	      if (!check_handled (types_caught, type))
  		{
! 		  types_caught = tree_cons (NULL, type, types_caught);
! 		  reachable_handlers
! 		    = tree_cons (void_type_node,
! 				 VARRAY_TREE (eh_stack, i),
! 				 reachable_handlers);
  		}
- 	    }
  
! 	  skip_cleanups = 0;
  	}
        else if (TREE_CODE (handler) == EH_FILTER_EXPR)
  	{
--- 4174,4226 ----
        tree handler = VARRAY_TREE (eh_stack, i);
        tree tp_node;
  
!       if (TREE_CODE (handler) == CATCH_EXPR
! 	  || (TREE_CODE (handler) == COMPOUND_EXPR
! 	      && TREE_CODE (TREE_OPERAND (handler, 0)) == CATCH_EXPR))
  	{
! 	  for (si = tsi_start (&handler); !tsi_end_p (si); tsi_next (&si))
  	    {
! 	      tree types;
  
! 	      handler = tsi_stmt (si);
! 	      types = CATCH_TYPES (handler);
  
! 	      /* This is a try/catch construct.  If it has no
! 		 CATCH_TYPES, then it catches all types and we
! 		 can stop our search early.  */
! 	      if (types == NULL_TREE)
  		{
! 		  reachable_handlers = tree_cons (void_type_node,
! 						  handler,
! 						  reachable_handlers);
! 		  goto out;
  		}
  
! 	      /* If TYPES is not a list, make it a list to
! 		 simplify handling below.  */
! 	      if (TREE_CODE (types) != TREE_LIST)
! 		types = tree_cons (NULL_TREE, types, NULL_TREE);
! 
! 	      /* See if the CATCH_TYPES specifies any types that have
! 		 not already been handled.  If so, add those types to
! 		 the types we handle and add this handler to the list
! 		 of reachable handlers.  */
! 	      for (tp_node = types; tp_node; tp_node = TREE_CHAIN (tp_node))
! 		{
! 		  tree type = TREE_VALUE (tp_node);
! 
! 		  if (!check_handled (types_caught, type))
! 		    {
! 		      types_caught = tree_cons (NULL, type, types_caught);
! 		      reachable_handlers
! 			= tree_cons (void_type_node,
! 				     handler,
! 				     reachable_handlers);
! 		    }
! 		}
! 
! 	      skip_cleanups = 0;
! 	    }
  	}
        else if (TREE_CODE (handler) == EH_FILTER_EXPR)
  	{
*************** compute_reachable_eh (tree stmt)
*** 4220,4226 ****
  	  if (EH_FILTER_TYPES (handler) == NULL_TREE)
  	    {
  	      reachable_handlers = tree_cons (void_type_node,
! 					      VARRAY_TREE (eh_stack, i),
  					      reachable_handlers);
  	      break;
  	    }
--- 4229,4235 ----
  	  if (EH_FILTER_TYPES (handler) == NULL_TREE)
  	    {
  	      reachable_handlers = tree_cons (void_type_node,
! 					      handler,
  					      reachable_handlers);
  	      break;
  	    }
*************** compute_reachable_eh (tree stmt)
*** 4229,4235 ****
  	     stop our search.  We should probably track the
  	     types it can throw.  */
  	  reachable_handlers = tree_cons (void_type_node,
! 					  VARRAY_TREE (eh_stack, i),
  					  reachable_handlers);
  
  	  skip_cleanups = 0;
--- 4238,4244 ----
  	     stop our search.  We should probably track the
  	     types it can throw.  */
  	  reachable_handlers = tree_cons (void_type_node,
! 					  handler,
  					  reachable_handlers);
  
  	  skip_cleanups = 0;
*************** compute_reachable_eh (tree stmt)
*** 4240,4251 ****
  	     stop our search; however, we can skip other
  	     cleanups until we run into something else.  */
  	  reachable_handlers = tree_cons (void_type_node,
! 					  VARRAY_TREE (eh_stack, i),
  					  reachable_handlers);
  	  skip_cleanups = 1;
  	}
      }
  
    /* REACHABLE_HANDLERS now contains a list of all the reachable
       handlers.  */
    stmt_ann (stmt)->reachable_exception_handlers = reachable_handlers;
--- 4249,4261 ----
  	     stop our search; however, we can skip other
  	     cleanups until we run into something else.  */
  	  reachable_handlers = tree_cons (void_type_node,
! 					  handler,
  					  reachable_handlers);
  	  skip_cleanups = 1;
  	}
      }
  
+  out:
    /* REACHABLE_HANDLERS now contains a list of all the reachable
       handlers.  */
    stmt_ann (stmt)->reachable_exception_handlers = reachable_handlers;

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