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++) another nothrow patch


2000-03-13  Jason Merrill  <jason@casey.cygnus.com>

	* decl.c (grokfndecl): Set TREE_NOTHROW if TYPE_NOTHROW_P.

	* except.c (dtor_nothrow): New fn.
	(do_pop_exception): Use it.  Take type parm.
	(push_eh_cleanup): Take type parm.
	(expand_start_catch_block): Pass it.
	(build_eh_type_type_ref): Accept null type.

Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.567
diff -c -p -r1.567 decl.c
*** decl.c	2000/03/13 04:54:39	1.567
--- decl.c	2000/03/13 19:18:25
*************** grokfndecl (ctype, type, declarator, ori
*** 8771,8777 ****
         tentative.  error_mark_node is replaced later with the BLOCK.  */
      DECL_INITIAL (decl) = error_mark_node;
  
!   if (nothrow_libfn_p (decl))
      TREE_NOTHROW (decl) = 1;
  
    /* Caller will do the rest of this.  */
--- 8771,8777 ----
         tentative.  error_mark_node is replaced later with the BLOCK.  */
      DECL_INITIAL (decl) = error_mark_node;
  
!   if (TYPE_NOTHROW_P (type) || nothrow_libfn_p (decl))
      TREE_NOTHROW (decl) = 1;
  
    /* Caller will do the rest of this.  */
Index: except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/except.c,v
retrieving revision 1.103
diff -c -p -r1.103 except.c
*** except.c	2000/03/11 09:00:13	1.103
--- except.c	2000/03/13 19:18:26
*************** Boston, MA 02111-1307, USA.  */
*** 37,43 ****
  #include "toplev.h"
  #include "eh-common.h"
  
! static void push_eh_cleanup PARAMS ((void));
  static tree build_eh_type_type PARAMS ((tree));
  static tree call_eh_info PARAMS ((void));
  static void push_eh_info PARAMS ((void));
--- 37,43 ----
  #include "toplev.h"
  #include "eh-common.h"
  
! static void push_eh_cleanup PARAMS ((tree));
  static tree build_eh_type_type PARAMS ((tree));
  static tree call_eh_info PARAMS ((void));
  static void push_eh_info PARAMS ((void));
*************** static tree get_eh_type PARAMS ((void));
*** 48,54 ****
  static tree get_eh_caught PARAMS ((void));
  static tree get_eh_handlers PARAMS ((void));
  #endif
! static tree do_pop_exception PARAMS ((void));
  static tree build_eh_type_type_ref PARAMS ((tree));
  static tree build_terminate_handler PARAMS ((void));
  static tree alloc_eh_object PARAMS ((tree));
--- 48,55 ----
  static tree get_eh_caught PARAMS ((void));
  static tree get_eh_handlers PARAMS ((void));
  #endif
! static int dtor_nothrow PARAMS ((tree));
! static tree do_pop_exception PARAMS ((tree));
  static tree build_eh_type_type_ref PARAMS ((tree));
  static tree build_terminate_handler PARAMS ((void));
  static tree alloc_eh_object PARAMS ((tree));
*************** build_eh_type_type_ref (type)
*** 356,363 ****
  {
    tree exp;
  
!   if (type == error_mark_node)
!     return error_mark_node;
  
    /* peel back references, so they match.  */
    if (TREE_CODE (type) == REFERENCE_TYPE)
--- 357,364 ----
  {
    tree exp;
  
!   if (type == NULL_TREE || type == error_mark_node)
!     return type;
  
    /* peel back references, so they match.  */
    if (TREE_CODE (type) == REFERENCE_TYPE)
*************** build_eh_type_type_ref (type)
*** 376,381 ****
--- 377,383 ----
  /* This routine is called to mark all the symbols representing runtime
     type functions in the exception table as having been referenced.
     This will make sure code is emitted for them. Called from finish_file. */
+ 
  void 
  mark_all_runtime_matches () 
  {
*************** mark_all_runtime_matches () 
*** 401,413 ****
    free (ptr);
  }
  
  /* Build up a call to __cp_pop_exception, to destroy the exception object
!    for the current catch block.  HANDLER is either true or false, telling
!    the library whether or not it is being called from an exception handler;
!    if it is, it avoids destroying the object on rethrow.  */
  
  static tree
! do_pop_exception ()
  {
    tree fn, cleanup;
    fn = get_identifier ("__cp_pop_exception");
--- 403,434 ----
    free (ptr);
  }
  
+ /* Returns nonzero if cleaning up an exception of type TYPE (which can be
+    NULL_TREE for a ... handler) will not throw an exception.  */
+ 
+ static int
+ dtor_nothrow (type)
+      tree type;
+ {
+   tree fn;
+ 
+   if (type == NULL_TREE)
+     return 0;
+ 
+   if (! TYPE_HAS_DESTRUCTOR (type))
+     return 1;
+ 
+   fn = lookup_member (type, dtor_identifier, 0, 0);
+   fn = TREE_VALUE (fn);
+   return TREE_NOTHROW (fn);
+ }
+ 
  /* Build up a call to __cp_pop_exception, to destroy the exception object
!    for the current catch block if no others are currently using it.  */
  
  static tree
! do_pop_exception (type)
!      tree type;
  {
    tree fn, cleanup;
    fn = get_identifier ("__cp_pop_exception");
*************** do_pop_exception ()
*** 427,441 ****
    cleanup = lookup_name (get_identifier ("__exception_info"), 0);
    cleanup = build_function_call (fn, tree_cons
  				 (NULL_TREE, cleanup, NULL_TREE));
    return cleanup;
  }
  
  /* This routine creates the cleanup for the current exception.  */
  
  static void
! push_eh_cleanup ()
  {
!   finish_decl_cleanup (NULL_TREE, do_pop_exception ());
  }
  
  /* Build up a call to terminate on the function obstack, for use as an
--- 448,464 ----
    cleanup = lookup_name (get_identifier ("__exception_info"), 0);
    cleanup = build_function_call (fn, tree_cons
  				 (NULL_TREE, cleanup, NULL_TREE));
+   TREE_NOTHROW (cleanup) = dtor_nothrow (type);
    return cleanup;
  }
  
  /* This routine creates the cleanup for the current exception.  */
  
  static void
! push_eh_cleanup (type)
!      tree type;
  {
!   finish_decl_cleanup (NULL_TREE, do_pop_exception (type));
  }
  
  /* Build up a call to terminate on the function obstack, for use as an
*************** expand_start_catch_block (decl)
*** 587,593 ****
  {
    tree compound_stmt_1;
    tree compound_stmt_2;
-   tree type;
  
    if (! doing_eh (1))
      return NULL_TREE;
--- 610,615 ----
*************** expand_start_catch_block (decl)
*** 603,617 ****
    if (! decl || ! decl_is_java_type (TREE_TYPE (decl), 1))
      {
        /* The ordinary C++ case.  */
  
        if (decl)
! 	type = build_eh_type_type_ref (TREE_TYPE (decl));
        else
  	type = NULL_TREE;
!       begin_catch_block (type);
  
        push_eh_info ();
!       push_eh_cleanup ();
      }
    else
      {
--- 625,640 ----
    if (! decl || ! decl_is_java_type (TREE_TYPE (decl), 1))
      {
        /* The ordinary C++ case.  */
+       tree type;
  
        if (decl)
! 	type = TREE_TYPE (decl);
        else
  	type = NULL_TREE;
!       begin_catch_block (build_eh_type_type_ref (type));
  
        push_eh_info ();
!       push_eh_cleanup (type);
      }
    else
      {

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