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]

C++ PATCH to clean up EH code


It seemed pointless to me to have both a HANDLER tree code and another
START_CATCH_STMT.  In addition to the redundancy problem, it led to
problems with nesting consistency; we were failing to push and pop blocks
and EH regions in LIFO order (though that doesn't currently break
anything).  This patch cleans that up and removes a couple of redundant
blocks.

Tested i686-pc-linux-gnu.  Applied to trunk only.

2001-05-21  Jason Merrill  <jason_merrill@redhat.com>

	* cp-tree.def (START_CATCH_STMT): Lose.
	* dump.c (cp_dump_tree): Don't dump it.  Do dump HANDLER_PARMS.
	* tree.c (cp_statement_code_p): Don't case it.
	* semantics.c (cp_expand_stmt): Likewise.
	* except.c (expand_start_catch_block): Don't start any blocks.
	Return the type.
	(expand_end_catch_block): Don't end any blocks.
	* parse.y (handler): Don't pass anything from finish_handler_parms
	to finish_handler.
	* pt.c (tsubst_expr): Likewise.
	* semantics.c (begin_handler): Call note_level_for_catch here.
	(finish_handler_parms): Don't return anything.
	(genrtl_catch_block, begin_catch_block): Lose.
	(genrtl_handler): Call expand_start_catch here.

*** cp-tree.def.~1~	Tue May  1 21:54:57 2001
--- cp-tree.def	Mon May 21 14:42:35 2001
*************** DEFTREECODE (CTOR_STMT, "ctor_stmt", 'e'
*** 229,242 ****
     constructed.  If, after this point, the CLEANUP_DECL goes out of
     scope, the CLEANUP_EXPR must be run.  */
  DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 2)
- /* A START_CATCH_STMT marks the beginning of a catch handler for the
-    the START_CATCH_TYPE.  If this is CATCH_ALL_TYPE, then the handler
-    catches all types.  */
- DEFTREECODE (START_CATCH_STMT, "start_catch_stmt", 'e', 0)
  DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
  DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
  DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
  DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2)
  DEFTREECODE (HANDLER, "handler", 'e', 2)
  
  /* A MUST_NOT_THROW_EXPR wraps an expression that may not
--- 229,242 ----
     constructed.  If, after this point, the CLEANUP_DECL goes out of
     scope, the CLEANUP_EXPR must be run.  */
  DEFTREECODE (CLEANUP_STMT, "cleanup_stmt", 'e', 2)
  DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2)
  DEFTREECODE (RETURN_INIT, "return_init", 'e', 2)
  DEFTREECODE (TRY_BLOCK, "try_block", 'e', 2)
  DEFTREECODE (EH_SPEC_BLOCK, "eh_spec_block", 'e', 2)
+ /* A HANDLER wraps a catch handler for the HANDLER_TYPE.  If this is
+    CATCH_ALL_TYPE, then the handler catches all types.  The declaration of
+    the catch variable is in HANDLER_PARMS, and the body block in
+    HANDLER_BODY.  */
  DEFTREECODE (HANDLER, "handler", 'e', 2)
  
  /* A MUST_NOT_THROW_EXPR wraps an expression that may not
*** cp-tree.h.~1~	Sat May 19 00:24:16 2001
--- cp-tree.h	Mon May 21 14:40:36 2001
*************** enum ptrmemfunc_vbit_where_t
*** 3065,3072 ****
  #define FN_TRY_BLOCK_P(NODE)    TREE_LANG_FLAG_3 (TRY_BLOCK_CHECK (NODE))
  #define HANDLER_PARMS(NODE)     TREE_OPERAND (HANDLER_CHECK (NODE), 0)
  #define HANDLER_BODY(NODE)      TREE_OPERAND (HANDLER_CHECK (NODE), 1)
  #define SUBOBJECT_CLEANUP(NODE) TREE_OPERAND (SUBOBJECT_CHECK (NODE), 0)
- #define START_CATCH_TYPE(NODE)  TREE_TYPE (START_CATCH_STMT_CHECK (NODE))
  
  /* Nonzero if this CTOR_STMT is for the beginning of a constructor.  */
  #define CTOR_BEGIN_P(NODE) \
--- 3065,3072 ----
  #define FN_TRY_BLOCK_P(NODE)    TREE_LANG_FLAG_3 (TRY_BLOCK_CHECK (NODE))
  #define HANDLER_PARMS(NODE)     TREE_OPERAND (HANDLER_CHECK (NODE), 0)
  #define HANDLER_BODY(NODE)      TREE_OPERAND (HANDLER_CHECK (NODE), 1)
+ #define HANDLER_TYPE(NODE)	TREE_TYPE (HANDLER_CHECK (NODE))
  #define SUBOBJECT_CLEANUP(NODE) TREE_OPERAND (SUBOBJECT_CHECK (NODE), 0)
  
  /* Nonzero if this CTOR_STMT is for the beginning of a constructor.  */
  #define CTOR_BEGIN_P(NODE) \
*************** extern cp_printer *cp_printers[256];
*** 4009,4015 ****
  /* in except.c */
  extern void init_exception_processing		PARAMS ((void));
  extern tree expand_start_catch_block		PARAMS ((tree));
! extern void expand_end_catch_block		PARAMS ((tree));
  extern void expand_builtin_throw		PARAMS ((void));
  extern void expand_eh_spec_block	        PARAMS ((tree));
  extern void expand_exception_blocks		PARAMS ((void));
--- 4009,4015 ----
  /* in except.c */
  extern void init_exception_processing		PARAMS ((void));
  extern tree expand_start_catch_block		PARAMS ((tree));
! extern void expand_end_catch_block		PARAMS ((void));
  extern void expand_builtin_throw		PARAMS ((void));
  extern void expand_eh_spec_block	        PARAMS ((tree));
  extern void expand_exception_blocks		PARAMS ((void));
*************** extern void finish_function_try_block   
*** 4275,4283 ****
  extern void finish_function_handler_sequence    PARAMS ((tree));
  extern void finish_cleanup_try_block            PARAMS ((tree));
  extern tree begin_handler                       PARAMS ((void));
! extern tree finish_handler_parms                PARAMS ((tree, tree));
  extern void begin_catch_block                   PARAMS ((tree));
! extern void finish_handler                      PARAMS ((tree, tree));
  extern void finish_cleanup                      PARAMS ((tree, tree));
  extern tree begin_compound_stmt                 PARAMS ((int));
  extern tree finish_compound_stmt                PARAMS ((int, tree));
--- 4275,4283 ----
  extern void finish_function_handler_sequence    PARAMS ((tree));
  extern void finish_cleanup_try_block            PARAMS ((tree));
  extern tree begin_handler                       PARAMS ((void));
! extern void finish_handler_parms                PARAMS ((tree, tree));
  extern void begin_catch_block                   PARAMS ((tree));
! extern void finish_handler                      PARAMS ((tree));
  extern void finish_cleanup                      PARAMS ((tree, tree));
  extern tree begin_compound_stmt                 PARAMS ((int));
  extern tree finish_compound_stmt                PARAMS ((int, tree));
*** decl.c.~1~	Sat May 19 00:24:17 2001
--- decl.c	Sat May 19 00:22:37 2001
*************** grokdeclarator (declarator, declspecs, d
*** 10064,10072 ****
  
        explicit_int = -1;
  
! 	  /* We handle `main' specially here, because 'main () { }' is so
! 	     common.  With no options, it is allowed.  With -Wreturn-type,
! 	     it is a warning.  It is only an error with -pedantic-errors.  */
        is_main = (funcdef_flag
  		 && MAIN_NAME_P (dname)
  		 && ctype == NULL_TREE
--- 10064,10072 ----
  
        explicit_int = -1;
  
!       /* We handle `main' specially here, because 'main () { }' is so
! 	 common.  With no options, it is allowed.  With -Wreturn-type,
! 	 it is a warning.  It is only an error with -pedantic-errors.  */
        is_main = (funcdef_flag
  		 && MAIN_NAME_P (dname)
  		 && ctype == NULL_TREE
*** dump.c.~1~	Fri May 18 10:18:58 2001
--- dump.c	Mon May 21 14:53:01 2001
*************** cp_dump_tree (di, t)
*** 230,235 ****
--- 230,236 ----
  
      case HANDLER:
        dump_stmt (di, t);
+       dump_child ("parm", HANDLER_PARMS (t));
        dump_child ("body", HANDLER_BODY (t));
        dump_next_stmt (di, t);
        break;
*************** cp_dump_tree (di, t)
*** 243,254 ****
      case SUBOBJECT:
        dump_stmt (di, t);
        dump_child ("clnp", TREE_OPERAND (t, 0));
-       dump_next_stmt (di, t);
-       break;
- 
-     case START_CATCH_STMT:
-       dump_stmt (di, t);
-       queue_and_dump_type (di, t);
        dump_next_stmt (di, t);
        break;
  
--- 244,249 ----
*** except.c.~1~	Sat May 19 00:24:17 2001
--- except.c	Mon May 21 14:05:47 2001
*************** tree
*** 391,398 ****
  expand_start_catch_block (decl)
       tree decl;
  {
-   tree compound_stmt_1;
-   tree compound_stmt_2;
    tree exp = NULL_TREE;
    tree type;
    bool is_java;
--- 391,396 ----
*************** expand_start_catch_block (decl)
*** 404,419 ****
    if (decl && !complete_ptr_ref_or_void_ptr_p (TREE_TYPE (decl), NULL_TREE))
      decl = NULL_TREE;
  
-   /* Create a binding level for the eh_info and the exception object
-      cleanup.  */
-   compound_stmt_1 = begin_compound_stmt (/*has_no_scope=*/0);
-   note_level_for_catch ();
- 
    if (decl)
      type = prepare_eh_type (TREE_TYPE (decl));
    else
      type = NULL_TREE;
-   begin_catch_block (type);
  
    is_java = false;
    if (decl)
--- 402,411 ----
*************** expand_start_catch_block (decl)
*** 452,464 ****
    if (! is_java)
      push_eh_cleanup (type);
  
-   /* Create a binding level for the parm.  */
-   compound_stmt_2 = begin_compound_stmt (/*has_no_scope=*/0);
- 
    if (decl)
      initialize_handler_parm (decl, exp);
  
!   return build_tree_list (compound_stmt_1, compound_stmt_2);
  }
  
  
--- 444,453 ----
    if (! is_java)
      push_eh_cleanup (type);
  
    if (decl)
      initialize_handler_parm (decl, exp);
  
!   return type;
  }
  
  
*************** expand_start_catch_block (decl)
*** 467,478 ****
     the label to jump to if this catch block didn't match.  */
  
  void
! expand_end_catch_block (blocks)
!      tree blocks;
  {
-   tree compound_stmt_1 = blocks ? TREE_PURPOSE (blocks): NULL_TREE;
-   tree compound_stmt_2 = blocks ? TREE_VALUE (blocks): NULL_TREE;
- 
    if (! doing_eh (1))
      return;
  
--- 456,463 ----
     the label to jump to if this catch block didn't match.  */
  
  void
! expand_end_catch_block ()
  {
    if (! doing_eh (1))
      return;
  
*************** expand_end_catch_block (blocks)
*** 482,492 ****
        && (DECL_CONSTRUCTOR_P (current_function_decl)
  	  || DECL_DESTRUCTOR_P (current_function_decl)))
      finish_expr_stmt (build_throw (NULL_TREE));
- 
-   /* Cleanup the EH parameter.  */
-   finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_2);
-   /* Cleanup the EH object.  */
-   finish_compound_stmt (/*has_no_scope=*/0, compound_stmt_1);
  }
  
  tree
--- 467,472 ----
*** parse.y.~1~	Sat May 19 00:24:17 2001
--- parse.y	Fri May 18 20:00:26 2001
*************** handler_seq:
*** 3518,3528 ****
  
  handler:
  	  CATCH
!                 { $<ttype>$ = begin_handler(); }
            handler_args
!                 { $<ttype>$ = finish_handler_parms ($3, $<ttype>2); }
  	  compstmt
!                 { finish_handler ($<ttype>4, $<ttype>2); }
  	;
  
  type_specifier_seq:
--- 3518,3528 ----
  
  handler:
  	  CATCH
!                 { $<ttype>$ = begin_handler (); }
            handler_args
!                 { finish_handler_parms ($3, $<ttype>2); }
  	  compstmt
!                 { finish_handler ($<ttype>2); }
  	;
  
  type_specifier_seq:
*** pt.c.~1~	Sat May 19 00:24:17 2001
--- pt.c	Sat May 19 00:07:16 2001
*************** tsubst_expr (t, args, complain, in_decl)
*** 7445,7451 ****
      case HANDLER:
        {
  	tree decl;
- 	tree blocks;
  
  	prep_stmt (t);
  	stmt = begin_handler ();
--- 7445,7450 ----
*************** tsubst_expr (t, args, complain, in_decl)
*** 7460,7468 ****
  	  }
  	else
  	  decl = NULL_TREE;
! 	blocks = finish_handler_parms (decl, stmt);
  	tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
! 	finish_handler (blocks, stmt);
        }
        break;
  
--- 7459,7467 ----
  	  }
  	else
  	  decl = NULL_TREE;
! 	finish_handler_parms (decl, stmt);
  	tsubst_expr (HANDLER_BODY (t), args, complain, in_decl);
! 	finish_handler (stmt);
        }
        break;
  
*** semantics.c.~1~	Sat May 19 00:24:17 2001
--- semantics.c	Mon May 21 14:40:05 2001
*************** static void emit_associated_thunks PARAM
*** 54,60 ****
  static void genrtl_try_block PARAMS ((tree));
  static void genrtl_eh_spec_block PARAMS ((tree));
  static void genrtl_handler PARAMS ((tree));
- static void genrtl_catch_block PARAMS ((tree));
  static void genrtl_ctor_stmt PARAMS ((tree));
  static void genrtl_subobject PARAMS ((tree));
  static void genrtl_named_return_value PARAMS ((void));
--- 54,59 ----
*************** genrtl_handler (t)
*** 721,726 ****
--- 720,727 ----
       tree t;
  {
    genrtl_do_pushlevel ();
+   if (!processing_template_decl)
+     expand_start_catch (HANDLER_TYPE (t));
    expand_stmt (HANDLER_BODY (t));
    if (!processing_template_decl)
      expand_end_catch ();
*************** begin_handler ()
*** 734,740 ****
--- 735,744 ----
    tree r;
    r = build_stmt (HANDLER, NULL_TREE, NULL_TREE);
    add_stmt (r);
+   /* Create a binding level for the eh_info and the exception object
+      cleanup.  */
    do_pushlevel ();
+   note_level_for_catch ();
    return r;
  }
  
*************** begin_handler ()
*** 742,754 ****
     HANDLER.  DECL is the declaration for the catch parameter, or NULL
     if this is a `catch (...)' clause.  */
  
! tree
  finish_handler_parms (decl, handler)
       tree decl;
       tree handler;
  {
!   tree blocks = NULL_TREE;
! 
    if (processing_template_decl)
      {
        if (decl)
--- 746,757 ----
     HANDLER.  DECL is the declaration for the catch parameter, or NULL
     if this is a `catch (...)' clause.  */
  
! void
  finish_handler_parms (decl, handler)
       tree decl;
       tree handler;
  {
!   tree type = NULL_TREE;
    if (processing_template_decl)
      {
        if (decl)
*************** finish_handler_parms (decl, handler)
*** 757,803 ****
  	  decl = push_template_decl (decl);
  	  add_decl_stmt (decl);
  	  RECHAIN_STMTS (handler, HANDLER_PARMS (handler));
  	}
      }
    else
!     blocks = expand_start_catch_block (decl);
! 
!   if (decl)
!     TREE_TYPE (handler) = TREE_TYPE (decl);
! 
!   return blocks;
! }
! 
! /* Generate the RTL for a START_CATCH_STMT. */
  
! static void
! genrtl_catch_block (type)
!      tree type;
! {
!   expand_start_catch (type);
! }
! 
! /* Note the beginning of a handler for TYPE.  This function is called
!    at the point to which control should be transferred when an
!    appropriately-typed exception is thrown.  */
! 
! void
! begin_catch_block (type)
!      tree type;
! {
!   add_stmt (build (START_CATCH_STMT, type));
  }
  
  /* Finish a handler, which may be given by HANDLER.  The BLOCKs are
     the return value from the matching call to finish_handler_parms.  */
  
  void
! finish_handler (blocks, handler)
!      tree blocks;
       tree handler;
  {
    if (!processing_template_decl)
!       expand_end_catch_block (blocks);
    do_poplevel ();
    RECHAIN_STMTS (handler, HANDLER_BODY (handler));
  }
--- 760,783 ----
  	  decl = push_template_decl (decl);
  	  add_decl_stmt (decl);
  	  RECHAIN_STMTS (handler, HANDLER_PARMS (handler));
+ 	  type = TREE_TYPE (decl);
  	}
      }
    else
!     type = expand_start_catch_block (decl);
  
!   HANDLER_TYPE (handler) = type;
  }
  
  /* Finish a handler, which may be given by HANDLER.  The BLOCKs are
     the return value from the matching call to finish_handler_parms.  */
  
  void
! finish_handler (handler)
       tree handler;
  {
    if (!processing_template_decl)
!     expand_end_catch_block ();
    do_poplevel ();
    RECHAIN_STMTS (handler, HANDLER_BODY (handler));
  }
*************** cp_expand_stmt (t)
*** 2165,2174 ****
      {
      case CLEANUP_STMT:
        genrtl_decl_cleanup (CLEANUP_DECL (t), CLEANUP_EXPR (t));
-       break;
- 
-     case START_CATCH_STMT:
-       genrtl_catch_block (TREE_TYPE (t));
        break;
  
      case CTOR_STMT:
--- 2145,2150 ----
*** tree.c.~1~	Fri May 18 10:18:59 2001
--- tree.c	Mon May 21 14:51:10 2001
*************** cp_statement_code_p (code)
*** 1031,1037 ****
      {
      case SUBOBJECT:
      case CLEANUP_STMT:
-     case START_CATCH_STMT:
      case CTOR_STMT:
      case CTOR_INITIALIZER:
      case RETURN_INIT:
--- 1031,1036 ----


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