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 build_throw


The C++ standard says that if an exception is thrown between the evaluation
of the expression to be thrown and it being caught, terminate() is called.
For some reason, when Richard rewrote the EH code (yay!) he changed this
behavior, so that instead it would free the allocated exception object
buffer and rethrow.  This patch restores the old, correct behavior, which
also generates less code.

Test in g++.eh/terminate1.C.

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

	* except.c (build_throw): Wrap the initialization of the exception
	object in a MUST_NOT_THROW_EXPR.
	(do_free_exception): #if 0.

*** except.c.~1~	Wed Mar 28 22:01:31 2001
--- except.c	Sun Apr 22 23:59:57 2001
*************** static bool decl_is_java_type PARAMS ((t
*** 46,52 ****
  static void choose_personality_routine PARAMS ((bool));
  static void initialize_handler_parm PARAMS ((tree, tree));
  static tree do_allocate_exception PARAMS ((tree));
- static tree do_free_exception PARAMS ((tree));
  static int complete_ptr_ref_or_void_ptr_p PARAMS ((tree, tree));
  static bool is_admissible_throw_operand PARAMS ((tree));
  static int can_convert_eh PARAMS ((tree, tree));
--- 46,51 ----
*************** do_allocate_exception (type)
*** 504,511 ****
  					     NULL_TREE));
  }
  
! /* Call __cxa_free_exception from a cleanup.  This is invoked when
!    a constructor for a thrown object throws.  */
  
  static tree
  do_free_exception (ptr)
--- 503,511 ----
  					     NULL_TREE));
  }
  
! #if 0
! /* Call __cxa_free_exception from a cleanup.  This is never invoked
!    directly.  */
  
  static tree
  do_free_exception (ptr)
*************** do_free_exception (ptr)
*** 525,530 ****
--- 525,531 ----
  
    return build_function_call (fn, tree_cons (NULL_TREE, ptr, NULL_TREE));
  }
+ #endif
  
  /* Build a throw expression.  */
  
*************** build_throw (exp)
*** 573,579 ****
        tree cleanup;
        tree stmt_expr;
        tree compound_stmt;
-       tree try_block;
        tree object, ptr;
        tree tmp;
  
--- 574,579 ----
*************** build_throw (exp)
*** 645,659 ****
        object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
        object = build_indirect_ref (object, NULL_PTR);
  
-       try_block = begin_try_block ();
- 
        exp = build_modify_expr (object, INIT_EXPR, exp);
        if (exp == error_mark_node)
  	error ("  in thrown expression");
  
        finish_expr_stmt (exp);
-       finish_cleanup_try_block (try_block);
-       finish_cleanup (do_free_exception (ptr), try_block);
  
        throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
  
--- 645,656 ----
        object = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (exp)), ptr);
        object = build_indirect_ref (object, NULL_PTR);
  
        exp = build_modify_expr (object, INIT_EXPR, exp);
        if (exp == error_mark_node)
  	error ("  in thrown expression");
  
+       exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp);
        finish_expr_stmt (exp);
  
        throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
  

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