Patch for TREE_NOTHROW

Jason Merrill jason@cygnus.com
Thu Mar 9 12:31:00 GMT 2000


This patch adds support for indicating at the tree level that a given
call will never throw an exception, and optimizing based on that
information.  Setting TREE_NOTHROW on a CALL_EXPR indicates that the
specific call will not throw; setting it on a FUNCTION_DECL indicates
that no calls to that function will throw.

We set this automatically on a function in rest_of_compilation if
we see that nothing in the function can throw.

We also assume that no libcalls, except calls to __throw et al, will
throw.

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

	* tree.h (struct tree_common): Rename raises_flag to nothrow_flag.
	(TREE_NOTHROW): Rename from TREE_RAISES.
	* toplev.c (rest_of_compilation): Set it.
	* print-tree.c (print_node): Adjust.
	* tree.c (stabilize_reference, build, build1): Don't set TREE_RAISES.
	(stabilize_reference_1, get_unwidened, get_narrower): Likewise.
	* calls.c (emit_call_1): Add 'nothrow' parm.  Add 
	REG_EH_REGION note as appropriate.
	(libfunc_nothrow): New fn.
	(emit_library_call, emit_library_call_value): Use it.
	(expand_call): Check TREE_NOTHROW.

cp/:
2000-03-09  Jason Merrill  <jason@casey.cygnus.com>

	* call.c (build_call): Set TREE_NOTHROW on the CALL_EXPR as
	appropriate.
	* decl.c (define_function): Set TREE_NOTHROW on the FUNCTION_DECL.
	* except.c (call_eh_info, alloc_eh_object, expand_throw): Set
	TREE_NOTHROW or TREE_THIS_VOLATILE on the function as appropriate.
	* rtti.c (build_runtime_decl, get_tinfo_decl, build_dynamic_cast_1,
	expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc,
	expand_generic_desc): Likewise.

Index: calls.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/calls.c,v
retrieving revision 1.90
diff -c -p -r1.90 calls.c
*** calls.c	2000/03/07 11:41:17	1.90
--- calls.c	2000/03/09 20:15:40
*************** calls.c	PARAMS ((tree,
*** 134,140 ****
  static int calls_function_1	PARAMS ((tree, int));
  static void emit_call_1		PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
  					 HOST_WIDE_INT, HOST_WIDE_INT, rtx,
! 					 rtx, int, rtx, int));
  static void precompute_register_parameters	PARAMS ((int,
  							 struct arg_data *,
  							 int *));
--- 134,140 ----
  static int calls_function_1	PARAMS ((tree, int));
  static void emit_call_1		PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
  					 HOST_WIDE_INT, HOST_WIDE_INT, rtx,
! 					 rtx, int, rtx, int, int));
  static void precompute_register_parameters	PARAMS ((int,
  							 struct arg_data *,
  							 int *));
*************** static void compute_argument_addresses		
*** 163,168 ****
--- 163,169 ----
  static rtx rtx_for_function_call		PARAMS ((tree, tree));
  static void load_register_parameters		PARAMS ((struct arg_data *,
  							 int, rtx *));
+ static int libfunc_nothrow			PARAMS ((rtx));
  
  #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
  static rtx save_fixed_argument_area	PARAMS ((int, rtx, int *, int *));
*************** prepare_call_address (funexp, fndecl, ca
*** 383,389 ****
  static void
  emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
  	     struct_value_size, next_arg_reg, valreg, old_inhibit_defer_pop,
! 	     call_fusage, is_const)
       rtx funexp;
       tree fndecl ATTRIBUTE_UNUSED;
       tree funtype ATTRIBUTE_UNUSED;
--- 384,390 ----
  static void
  emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
  	     struct_value_size, next_arg_reg, valreg, old_inhibit_defer_pop,
! 	     call_fusage, is_const, nothrow)
       rtx funexp;
       tree fndecl ATTRIBUTE_UNUSED;
       tree funtype ATTRIBUTE_UNUSED;
*************** emit_call_1 (funexp, fndecl, funtype, st
*** 394,400 ****
       rtx valreg;
       int old_inhibit_defer_pop;
       rtx call_fusage;
!      int is_const;
  {
    rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
  #if defined (HAVE_call) && defined (HAVE_call_value)
--- 395,401 ----
       rtx valreg;
       int old_inhibit_defer_pop;
       rtx call_fusage;
!      int is_const, nothrow;
  {
    rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
  #if defined (HAVE_call) && defined (HAVE_call_value)
*************** emit_call_1 (funexp, fndecl, funtype, st
*** 491,496 ****
--- 492,503 ----
    if (is_const)
      CONST_CALL_P (call_insn) = 1;
  
+   /* If this call can't throw, attach a REG_EH_REGION reg note to that
+      effect.  */
+   if (nothrow)
+     REG_NOTES (call_insn) = gen_rtx_EXPR_LIST (REG_EH_REGION, GEN_INT (-1),
+ 					       REG_NOTES (call_insn));
+ 
    /* Restore this now, so that we do defer pops for this call's args
       if the context of the call as a whole permits.  */
    inhibit_defer_pop = old_inhibit_defer_pop;
*************** expand_call (exp, target, ignore)
*** 1682,1687 ****
--- 1689,1696 ----
    int is_const = 0;
    /* Nonzero if this is a call to a `volatile' function.  */
    int is_volatile = 0;
+   /* Nonzero if this is a call to a function that won't throw an exception.  */
+   int nothrow = TREE_NOTHROW (exp);
  #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
    /* Define the boundary of the register parm stack space that needs to be
       save, if any.  */
*************** expand_call (exp, target, ignore)
*** 1756,1761 ****
--- 1765,1773 ----
  
  	  if (TREE_THIS_VOLATILE (fndecl))
  	    is_volatile = 1;
+ 
+ 	  if (TREE_NOTHROW (fndecl))
+ 	    nothrow = 1;
  	}
      }
  
*************** expand_call (exp, target, ignore)
*** 2418,2424 ****
    emit_call_1 (funexp, fndecl, funtype, unadjusted_args_size,
  	       args_size.constant, struct_value_size,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
! 	       valreg, old_inhibit_defer_pop, call_fusage, is_const);
  
    /* If call is cse'able, make appropriate pair of reg-notes around it.
       Test valreg so we don't crash; may safely ignore `const'
--- 2430,2436 ----
    emit_call_1 (funexp, fndecl, funtype, unadjusted_args_size,
  	       args_size.constant, struct_value_size,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
! 	       valreg, old_inhibit_defer_pop, call_fusage, is_const, nothrow);
  
    /* If call is cse'able, make appropriate pair of reg-notes around it.
       Test valreg so we don't crash; may safely ignore `const'
*************** expand_call (exp, target, ignore)
*** 2666,2671 ****
--- 2678,2699 ----
    return target;
  }
  
+ /* Returns nonzero if FUN is the symbol for a library function which can
+    not throw.  */
+ 
+ static int
+ libfunc_nothrow (fun)
+      rtx fun;
+ {
+   if (fun == throw_libfunc
+       || fun == rethrow_libfunc
+       || fun == sjthrow_libfunc
+       || fun == sjpopnthrow_libfunc)
+     return 0;
+ 
+   return 1;
+ }
+ 
  /* Output a library call to function FUN (a SYMBOL_REF rtx)
     (emitting the queue unless NO_QUEUE is nonzero),
     for a value of mode OUTMODE,
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 2714,2719 ****
--- 2742,2748 ----
    int old_inhibit_defer_pop = inhibit_defer_pop;
    rtx call_fusage = 0;
    int reg_parm_stack_space = 0;
+   int nothrow;
  #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
    /* Define the boundary of the register parm stack space that needs to be
       save, if any.  */
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 2747,2752 ****
--- 2776,2783 ----
  
    fun = orgfun;
  
+   nothrow = libfunc_nothrow (fun);
+ 
    /* Copy all the libcall-arguments out of the varargs data
       and into a vector ARGVEC.
  
*************** emit_library_call VPARAMS((rtx orgfun, i
*** 3139,3145 ****
  	       original_args_size.constant, args_size.constant, 0,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX,
! 	       old_inhibit_defer_pop + 1, call_fusage, no_queue);
  
    pop_temp_slots ();
  
--- 3170,3176 ----
  	       original_args_size.constant, args_size.constant, 0,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX,
! 	       old_inhibit_defer_pop + 1, call_fusage, no_queue, nothrow);
  
    pop_temp_slots ();
  
*************** emit_library_call_value VPARAMS((rtx org
*** 3234,3239 ****
--- 3265,3271 ----
    int struct_value_size = 0;
    int is_const;
    int reg_parm_stack_space = 0;
+   int nothrow;
  #ifdef ACCUMULATE_OUTGOING_ARGS
    int needed;
  #endif
*************** emit_library_call_value VPARAMS((rtx org
*** 3272,3277 ****
--- 3304,3311 ----
    is_const = no_queue;
    fun = orgfun;
  
+   nothrow = libfunc_nothrow (fun);
+ 
  #ifdef PREFERRED_STACK_BOUNDARY
    /* Ensure current function's preferred stack boundary is at least
       what we need.  */
*************** emit_library_call_value VPARAMS((rtx org
*** 3737,3743 ****
  	       struct_value_size,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       mem_value == 0 ? hard_libcall_value (outmode) : NULL_RTX,
! 	       old_inhibit_defer_pop + 1, call_fusage, is_const);
  
    /* Now restore inhibit_defer_pop to its actual original value.  */
    OK_DEFER_POP;
--- 3771,3777 ----
  	       struct_value_size,
  	       FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
  	       mem_value == 0 ? hard_libcall_value (outmode) : NULL_RTX,
! 	       old_inhibit_defer_pop + 1, call_fusage, is_const, nothrow);
  
    /* Now restore inhibit_defer_pop to its actual original value.  */
    OK_DEFER_POP;
Index: print-tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/print-tree.c,v
retrieving revision 1.25
diff -c -p -r1.25 print-tree.c
*** print-tree.c	2000/03/07 11:41:19	1.25
--- print-tree.c	2000/03/09 20:15:53
*************** print_node (file, prefix, node, indent)
*** 301,308 ****
      fputs (" asm_written", file);
    if (TREE_USED (node))
      fputs (" used", file);
!   if (TREE_RAISES (node))
!     fputs (" raises", file);
    if (!ggc_p && TREE_PERMANENT (node))
      fputs (" permanent", file);
    if (TREE_PUBLIC (node))
--- 301,308 ----
      fputs (" asm_written", file);
    if (TREE_USED (node))
      fputs (" used", file);
!   if (TREE_NOTHROW (node))
!     fputs (" nothrow", file);
    if (!ggc_p && TREE_PERMANENT (node))
      fputs (" permanent", file);
    if (TREE_PUBLIC (node))
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.301
diff -c -p -r1.301 toplev.c
*** toplev.c	2000/03/09 19:01:47	1.301
--- toplev.c	2000/03/09 20:15:57
*************** rest_of_compilation (decl)
*** 3679,3684 ****
--- 3679,3688 ----
  #endif
  
    current_function_nothrow = nothrow_function_p ();
+   if (current_function_nothrow)
+     /* Now we know that this can't throw; set the flag for the benefit
+        of other functions later in this translation unit.  */
+     TREE_NOTHROW (current_function_decl) = 1;
  
    /* Now turn the rtl into assembler code.  */
  
Index: tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.121
diff -c -p -r1.121 tree.c
*** tree.c	2000/03/07 11:41:19	1.121
--- tree.c	2000/03/09 20:16:00
*************** stabilize_reference (ref)
*** 3025,3031 ****
    TREE_READONLY (result) = TREE_READONLY (ref);
    TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref);
    TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref);
-   TREE_RAISES (result) = TREE_RAISES (ref);
  
    return result;
  }
--- 3025,3030 ----
*************** stabilize_reference_1 (e)
*** 3108,3114 ****
    TREE_READONLY (result) = TREE_READONLY (e);
    TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (e);
    TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (e);
-   TREE_RAISES (result) = TREE_RAISES (e);
  
    return result;
  }
--- 3107,3112 ----
*************** build VPARAMS ((enum tree_code code, tre
*** 3161,3175 ****
  	{
  	  if (TREE_SIDE_EFFECTS (arg0))
  	    TREE_SIDE_EFFECTS (t) = 1;
- 	  if (TREE_RAISES (arg0))
- 	    TREE_RAISES (t) = 1;
  	}
        if (arg1 && fro > 1)
  	{
  	  if (TREE_SIDE_EFFECTS (arg1))
  	    TREE_SIDE_EFFECTS (t) = 1;
- 	  if (TREE_RAISES (arg1))
- 	    TREE_RAISES (t) = 1;
  	}
      }
    else if (length == 1)
--- 3159,3169 ----
*************** build VPARAMS ((enum tree_code code, tre
*** 3184,3190 ****
  	{
  	  if (arg0 && TREE_SIDE_EFFECTS (arg0))
  	    TREE_SIDE_EFFECTS (t) = 1;
- 	  TREE_RAISES (t) = (arg0 && TREE_RAISES (arg0));
  	}
      }
    else
--- 3178,3183 ----
*************** build VPARAMS ((enum tree_code code, tre
*** 3197,3204 ****
  	    {
  	      if (TREE_SIDE_EFFECTS (operand))
  		TREE_SIDE_EFFECTS (t) = 1;
- 	      if (TREE_RAISES (operand))
- 		TREE_RAISES (t) = 1;
  	    }
  	}
      }
--- 3190,3195 ----
*************** build1 (code, type, node)
*** 3254,3261 ****
      {
        if (TREE_SIDE_EFFECTS (node))
  	TREE_SIDE_EFFECTS (t) = 1;
-       if (TREE_RAISES (node))
- 	TREE_RAISES (t) = 1;
      }
  
    switch (code)
--- 3245,3250 ----
*************** get_unwidened (op, for_type)
*** 4827,4833 ****
  		       TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
- 	  TREE_RAISES (win) = TREE_RAISES (op);
  	}
      }
    return win;
--- 4816,4821 ----
*************** get_narrower (op, unsignedp_ptr)
*** 4914,4920 ****
  		       TREE_OPERAND (op, 1));
  	  TREE_SIDE_EFFECTS (win) = TREE_SIDE_EFFECTS (op);
  	  TREE_THIS_VOLATILE (win) = TREE_THIS_VOLATILE (op);
- 	  TREE_RAISES (win) = TREE_RAISES (op);
  	}
      }
    *unsignedp_ptr = uns;
--- 4902,4907 ----
Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.139
diff -c -p -r1.139 tree.h
*** tree.h	2000/03/07 20:39:05	1.139
--- tree.h	2000/03/09 20:16:02
*************** struct tree_common
*** 206,212 ****
    unsigned asm_written_flag: 1;
  
    unsigned used_flag : 1;
!   unsigned raises_flag : 1;
    unsigned static_flag : 1;
    unsigned public_flag : 1;
    unsigned private_flag : 1;
--- 206,212 ----
    unsigned asm_written_flag: 1;
  
    unsigned used_flag : 1;
!   unsigned nothrow_flag : 1;
    unsigned static_flag : 1;
    unsigned public_flag : 1;
    unsigned private_flag : 1;
*************** struct tree_common
*** 322,331 ****
         TREE_USED in
             expressions, IDENTIFIER_NODE
  
!    raises_flag:
  
!        TREE_RAISES in
!            expressions
  
  							  */
  /* Define accessors for the fields that all tree nodes have
--- 322,331 ----
         TREE_USED in
             expressions, IDENTIFIER_NODE
  
!    nothrow_flag:
  
!        TREE_NOTHROW in
!            CALL_EXPR, FUNCTION_DECL
  
  							  */
  /* Define accessors for the fields that all tree nodes have
*************** extern void tree_class_check_failed PARA
*** 599,607 ****
     was used.  */
  #define TREE_USED(NODE) ((NODE)->common.used_flag)
  
! /* Nonzero for a tree node whose evaluation could result
!    in the raising of an exception.  Not implemented yet.  */
! #define TREE_RAISES(NODE) ((NODE)->common.raises_flag)
  
  /* Used in classes in C++.  */
  #define TREE_PRIVATE(NODE) ((NODE)->common.private_flag)
--- 599,607 ----
     was used.  */
  #define TREE_USED(NODE) ((NODE)->common.used_flag)
  
! /* In a FUNCTION_DECL, nonzero means a call to the function cannot throw
!    an exception.  In a CALL_EXPR, nonzero means the call cannot throw.  */
! #define TREE_NOTHROW(NODE) ((NODE)->common.nothrow_flag)
  
  /* Used in classes in C++.  */
  #define TREE_PRIVATE(NODE) ((NODE)->common.private_flag)
*************** struct tree_type
*** 1300,1313 ****
     contour that restored a stack level and which is now exited.  */
  #define DECL_TOO_LATE(NODE) (DECL_CHECK (NODE)->decl.bit_field_flag)
  
! /* In a FUNCTION_DECL, nonzero means a built in function.  */
! #define DECL_BUILT_IN(NODE) (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN)
! /* For a builtin function, identify which part of the compiler defined it.  */
! #define DECL_BUILT_IN_CLASS(NODE) (DECL_CHECK (NODE)->decl.built_in_class)
  
  /* In a VAR_DECL that's static,
     nonzero if the space is in the text section.  */
  #define DECL_IN_TEXT_SECTION(NODE) (DECL_CHECK (NODE)->decl.bit_field_flag)
  
  /* Used in VAR_DECLs to indicate that the variable is a vtable.
     Used in FIELD_DECLs for vtable pointers.
--- 1300,1315 ----
     contour that restored a stack level and which is now exited.  */
  #define DECL_TOO_LATE(NODE) (DECL_CHECK (NODE)->decl.bit_field_flag)
  
! /* Unused in FUNCTION_DECL.  */
  
  /* In a VAR_DECL that's static,
     nonzero if the space is in the text section.  */
  #define DECL_IN_TEXT_SECTION(NODE) (DECL_CHECK (NODE)->decl.bit_field_flag)
+ 
+ /* In a FUNCTION_DECL, nonzero means a built in function.  */
+ #define DECL_BUILT_IN(NODE) (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN)
+ /* For a builtin function, identify which part of the compiler defined it.  */
+ #define DECL_BUILT_IN_CLASS(NODE) (DECL_CHECK (NODE)->decl.built_in_class)
  
  /* Used in VAR_DECLs to indicate that the variable is a vtable.
     Used in FIELD_DECLs for vtable pointers.
Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.200
diff -c -p -r1.200 call.c
*** cp/call.c	2000/03/05 10:22:15	1.200
--- cp/call.c	2000/03/09 20:16:29
*************** build_call (function, result_type, parms
*** 368,373 ****
--- 368,374 ----
       tree function, result_type, parms;
  {
    int is_constructor = 0;
+   int nothrow;
    tree tmp;
    tree decl;
  
*************** build_call (function, result_type, parms
*** 385,390 ****
--- 386,396 ----
    else
      decl = NULL_TREE;
  
+   /* We check both the decl and the type; a function may be known not to
+      throw without being declared throw().  */
+   nothrow = ((decl && TREE_NOTHROW (decl))
+ 	     || TYPE_NOTHROW_P (TREE_TYPE (TREE_TYPE (function))));
+   
    if (decl && DECL_CONSTRUCTOR_P (decl))
      is_constructor = 1;
  
*************** build_call (function, result_type, parms
*** 408,413 ****
--- 414,420 ----
    TREE_HAS_CONSTRUCTOR (function) = is_constructor;
    TREE_TYPE (function) = result_type;
    TREE_SIDE_EFFECTS (function) = 1;
+   TREE_NOTHROW (function) = nothrow;
    
    return function;
  }
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.558
diff -c -p -r1.558 decl.c
*** cp/decl.c	2000/03/04 00:45:23	1.558
--- cp/decl.c	2000/03/09 20:16:40
*************** define_function (name, type, pfn, librar
*** 6418,6423 ****
--- 6418,6427 ----
    TREE_PUBLIC (decl) = 1;
    DECL_ARTIFICIAL (decl) = 1;
  
+   /* If no exception specifier was given, assume it doesn't throw.  */
+   if (TYPE_RAISES_EXCEPTIONS (type) == NULL_TREE)
+     TREE_NOTHROW (decl) = 1;
+ 
    my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392);
    DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
  
Index: cp/except.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/except.c,v
retrieving revision 1.98
diff -c -p -r1.98 except.c
*** cp/except.c	2000/03/02 19:58:49	1.98
--- cp/except.c	2000/03/09 20:16:41
*************** call_eh_info ()
*** 258,263 ****
--- 258,264 ----
        DECL_EXTERNAL (fn) = 1;
        TREE_PUBLIC (fn) = 1;
        DECL_ARTIFICIAL (fn) = 1;
+       TREE_NOTHROW (fn) = 1;
        pushdecl_top_level (fn);
        make_function_rtl (fn);
      }
*************** alloc_eh_object (type)
*** 805,810 ****
--- 806,812 ----
        DECL_EXTERNAL (fn) = 1;
        TREE_PUBLIC (fn) = 1;
        DECL_ARTIFICIAL (fn) = 1;
+       TREE_NOTHROW (fn) = 1;
        pushdecl_top_level (fn);
        make_function_rtl (fn);
      }
*************** expand_throw (exp)
*** 857,862 ****
--- 859,865 ----
  	  DECL_EXTERNAL (fn) = 1;
  	  TREE_PUBLIC (fn) = 1;
  	  DECL_ARTIFICIAL (fn) = 1;
+ 	  TREE_THIS_VOLATILE (fn) = 1;
  	  pushdecl_top_level (fn);
  	  make_function_rtl (fn);
  	}
*************** expand_throw (exp)
*** 976,981 ****
--- 979,985 ----
  	  DECL_EXTERNAL (fn) = 1;
  	  TREE_PUBLIC (fn) = 1;
  	  DECL_ARTIFICIAL (fn) = 1;
+ 	  TREE_NOTHROW (fn) = 1;
  	  pushdecl_top_level (fn);
  	  make_function_rtl (fn);
  	}
*************** expand_throw (exp)
*** 1005,1010 ****
--- 1009,1015 ----
  	  DECL_EXTERNAL (fn) = 1;
  	  TREE_PUBLIC (fn) = 1;
  	  DECL_ARTIFICIAL (fn) = 1;
+ 	  TREE_NOTHROW (fn) = 1;
  	  pushdecl_top_level (fn);
  	  make_function_rtl (fn);
  	}
Index: cp/rtti.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/rtti.c,v
retrieving revision 1.63
diff -c -p -r1.63 rtti.c
*** cp/rtti.c	2000/02/29 02:34:48	1.63
--- cp/rtti.c	2000/03/09 20:16:43
*************** build_runtime_decl (name, type)
*** 185,190 ****
--- 185,191 ----
        DECL_EXTERNAL (d) = 1;
        TREE_PUBLIC (d) = 1;
        DECL_ARTIFICIAL (d) = 1;
+       TREE_THIS_VOLATILE (d) = 1;
        pushdecl_top_level (d);
        make_function_rtl (d);
      }
*************** get_tinfo_decl (type)
*** 423,428 ****
--- 424,430 ----
        DECL_EXTERNAL (d) = 1;
        TREE_PUBLIC (d) = 1;
        DECL_ARTIFICIAL (d) = 1;
+       TREE_NOTHROW (d) = 1;
        DECL_NOT_REALLY_EXTERN (d) = 1;
        SET_DECL_TINFO_FN_P (d);
        TREE_TYPE (name) = type;
*************** build_dynamic_cast_1 (type, expr)
*** 818,826 ****
  	      DECL_EXTERNAL (dcast_fn) = 1;
  	      TREE_PUBLIC (dcast_fn) = 1;
  	      DECL_ARTIFICIAL (dcast_fn) = 1;
  	      pushdecl (dcast_fn);
  	      if (new_abi_rtti_p ())
! 	        /* We want it's name mangling.  */
  	        set_mangled_name_for_decl (dcast_fn);
  	      make_function_rtl (dcast_fn);
                pop_nested_namespace (ns);
--- 820,829 ----
  	      DECL_EXTERNAL (dcast_fn) = 1;
  	      TREE_PUBLIC (dcast_fn) = 1;
  	      DECL_ARTIFICIAL (dcast_fn) = 1;
+ 	      TREE_NOTHROW (dcast_fn) = 1;
  	      pushdecl (dcast_fn);
  	      if (new_abi_rtti_p ())
! 	        /* We want its name mangling.  */
  	        set_mangled_name_for_decl (dcast_fn);
  	      make_function_rtl (dcast_fn);
                pop_nested_namespace (ns);
*************** expand_si_desc (tdecl, type)
*** 915,920 ****
--- 918,924 ----
        DECL_EXTERNAL (fn) = 1;
        TREE_PUBLIC (fn) = 1;
        DECL_ARTIFICIAL (fn) = 1;
+       TREE_NOTHROW (fn) = 1;
        pushdecl_top_level (fn);
        make_function_rtl (fn);
      }
*************** expand_class_desc (tdecl, type)
*** 1074,1079 ****
--- 1078,1084 ----
        DECL_EXTERNAL (fn) = 1;
        TREE_PUBLIC (fn) = 1;
        DECL_ARTIFICIAL (fn) = 1;
+       TREE_NOTHROW (fn) = 1;
        pushdecl_top_level (fn);
        make_function_rtl (fn);
      }
*************** expand_ptr_desc (tdecl, type)
*** 1118,1123 ****
--- 1123,1129 ----
        DECL_EXTERNAL (fn) = 1;
        TREE_PUBLIC (fn) = 1;
        DECL_ARTIFICIAL (fn) = 1;
+       TREE_NOTHROW (fn) = 1;
        pushdecl_top_level (fn);
        make_function_rtl (fn);
      }
*************** expand_attr_desc (tdecl, type)
*** 1163,1168 ****
--- 1169,1175 ----
        DECL_EXTERNAL (fn) = 1;
        TREE_PUBLIC (fn) = 1;
        DECL_ARTIFICIAL (fn) = 1;
+       TREE_NOTHROW (fn) = 1;
        pushdecl_top_level (fn);
        make_function_rtl (fn);
      }
*************** expand_generic_desc (tdecl, type, fnname
*** 1200,1205 ****
--- 1207,1213 ----
        DECL_EXTERNAL (fn) = 1;
        TREE_PUBLIC (fn) = 1;
        DECL_ARTIFICIAL (fn) = 1;
+       TREE_NOTHROW (fn) = 1;
        pushdecl_top_level (fn);
        make_function_rtl (fn);
      }


More information about the Gcc-patches mailing list