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]

Re: [PATCH] Merge from LTO: eh_personality changes


On Thu, 10 Sep 2009, Richard Guenther wrote:

> On Thu, 10 Sep 2009, Richard Guenther wrote:
> 
> > On Tue, 8 Sep 2009, Richard Henderson wrote:
> > 
> > > On 09/08/2009 08:20 AM, Richard Guenther wrote:
> > > > > Ok.  I'll modify the patch to make this a true langhook and maybe move
> > > > > the eh-personality also to a langhook called from eh lowering.
> > > > 
> > > > The latter is difficult as C++ is playing some tricks with Java vs.
> > > > non-Java personality, so I leave that alone for now.
> > > 
> > > Ew.
> > > 
> > > > FYI the following two patches would implement the above (untested).
> > > 
> > > Looks good.
> > 
> > I've been playing a bit with optimizing setting of 
> > DECL_FUNCTION_EH_PERSONALITY only if the function uses EH types
> > instead of just checking for an empty EH region tree.  It doesn't look
> > like its very simple - even a catch (...) needs a personality routine.
> > 
> > So I am now testing the following - the ERT_ALLOWED_EXCEPTIONS case
> > is required to get diagnostics from g++.dg/torture/pr34850.C which
> > requires inlining memset into clear_mem.
> > 
> > If that doesn't work out I'll refrain from optimizing at all and
> > just disable cross different EH personality TU inlining completely
> > (that already passed bootstrapping and testing, it would be
> > -  if (function_needs_eh_personality (cfun))
> > -    DECL_FUNCTION_PERSONALITY (current_function_decl) = 
> > eh_personality_decl;
> > +  DECL_FUNCTION_PERSONALITY (current_function_decl) = 
> > eh_personality_decl;
> > meaning no functional change as far as trunk is concerned)
> 
> Doesn't seem to work.  Instead I tried to fall back to
> the gcc personality for detecting empty type lists, again setting
> a cfi personality for all functions we emit.  But that doesn't work
> either (it seems catch (...) doesn't work with the gcc personality,
> g++.dg/eh/loop1.C fails).

Which would be the following patch.

Richard.

2009-09-10  Richard Guenther  <rguenther@suse.de>
	Rafael Avila de Espindola  <espindola@google.com>

	* langhooks-def.h (LANG_HOOKS_INIT_EH): Define.
	(LANG_HOOKS_EH_RUNTIME_TYPE): Likewise.
	(LANG_HOOKS_INITIALIZER): Adjust.
	(lhd_pass_through_t): Declare.
	* langhooks.h (struct lang_hooks): Add init_eh and eh_runtime_type.
	* langhooks.c (lhd_pass_through_t): New function.

        * dwarf2out.c (output_call_frame_info, dwarf2out_do_cfi_startproc,
	dwarf2out_begin_prologue): Use personality from current_function_decl.
        * expr.h (build_personality_function): Declare.
	(get_personality_function): Likewise.
	* expr.c (get_personality_function): New function.
        * libfuncs.h (libfunc_index): Remove LTI_eh_personality.
        (eh_personality_libfunc): Remove.
        * optabs.c (build_libfunc_function): New function split out from ...
	(init_one_libfunc): ... here.
        * toplev.c (eh_personality_decl): New.
        * tree.h (DECL_FUNCTION_PERSONALITY): New.
        (tree_function_decl): Add personality.
        (eh_personality_decl): New.
	* except.h (lang_eh_runtime_type): Remove.
	(function_needs_eh_personality): Declare.
        * except.c (lang_eh_runtime_type): Remove.
	(function_needs_eh_personality): New function.
	(add_type_for_runtime): Call lang_hooks.type_for_runtime instead.
        (sjlj_emit_function_enter, output_function_exception_table):
        Use personality from current_function_decl.
	* tree-eh.c (lower_eh_constructs): Set DECL_FUNCTION_PERSONALITY.
	* tree-inline.c (tree_can_inline_p): Do not inline across different
	EH personalities.

	* c-lang.c (LANG_HOOKS_INIT_EH): Define.
	* c-tree.h (c_eh_initialized_p): Remove.
	* c-decl.c (finish_decl): Don't call c_maybe_initialize_eh.
	Init eh_personality_decl instead of eh_personality_libfunc.
	(finish_decl): Don't call c_maybe_initialize_eh.
	(c_eh_initialized_p): Make local to ...
	(c_maybe_initialize_eh): ... this function.
	Init eh_personality_decl instead of eh_personality_libfunc.
        * c-parser.c (c_parser_omp_construct): Likewise.
	(c_parse_file): Call lang_hooks.init_eh.

	objc/
	* objc-act.c (objc_eh_runtime_type): Export.
	(objc_init_exceptions): Export.
	Init eh_personality_decl instead of eh_personality_libfunc.
	Do not set objc_init_exceptions.  Move warning code ...
	(objc_begin_try_stmt): ... here
	(objc_build_throw_stmt): ... and here.
	* objc-act.h (objc_init_exceptions): Declare.
	(objc_eh_runtime_type): Likewise.
	* objc-lang.c (LANG_HOOKS_INIT_EH): Define.
	(LANG_HOOKS_EH_RUNTIME_TYPE): Likewise.

	cp/
	* except.c (init_exception_processing): Do not set
	lang_eh_runtime_type.
	Init eh_personality_decl instead of eh_personality_libfunc.
	* cp-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define.

	java/
	* decl.c (do_nothing): Remove.
	(java_init_decl_processing): Do not set lang_eh_runtime_type.
	Init eh_personality_decl instead of eh_personality_libfunc.

	ada/
	* gcc-interface/misc.c (gnat_init_gcc_eh): Do not set
	lang_eh_runtime_type.
	Init eh_personality_decl instead of eh_personality_libfunc.

	fortran/
	* f95-lang.c (gfc_maybe_initialize_eh): Init eh_personality_decl
	instead of eh_personality_libfunc.

Index: gcc/objc/objc-act.c
===================================================================
*** gcc/objc/objc-act.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/objc/objc-act.c	2009-09-10 14:18:42.000000000 +0200
*************** static struct objc_try_context *cur_try_
*** 3488,3494 ****
  /* ??? Isn't there a class object or some such?  Is it easy to get?  */
  
  #ifndef OBJCPLUS
! static tree
  objc_eh_runtime_type (tree type)
  {
    return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
--- 3488,3494 ----
  /* ??? Isn't there a class object or some such?  Is it easy to get?  */
  
  #ifndef OBJCPLUS
! tree
  objc_eh_runtime_type (tree type)
  {
    return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
*************** objc_eh_runtime_type (tree type)
*** 3497,3503 ****
  
  /* Initialize exception handling.  */
  
! static void
  objc_init_exceptions (void)
  {
    static bool done = false;
--- 3497,3503 ----
  
  /* Initialize exception handling.  */
  
! void
  objc_init_exceptions (void)
  {
    static bool done = false;
*************** objc_init_exceptions (void)
*** 3505,3529 ****
      return;
    done = true;
  
-   if (flag_objc_sjlj_exceptions)
-     {
-       /* On Darwin, ObjC exceptions require a sufficiently recent
- 	 version of the runtime, so the user must ask for them explicitly.  */
-       if (!flag_objc_exceptions)
- 	warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
- 		 "exception syntax");
-     }
  #ifndef OBJCPLUS
!   else
      {
!       c_eh_initialized_p = true;
!       eh_personality_libfunc
! 	= init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 			    ? "__gnu_objc_personality_sj0"
! 			    : "__gnu_objc_personality_v0");
        default_init_unwind_resume_libfunc ();
        using_eh_for_cleanups ();
-       lang_eh_runtime_type = objc_eh_runtime_type;
      }
  #endif
  }
--- 3505,3519 ----
      return;
    done = true;
  
  #ifndef OBJCPLUS
!   if (!flag_objc_sjlj_exceptions)
      {
!       eh_personality_decl
! 	= build_personality_function (USING_SJLJ_EXCEPTIONS
! 				      ? "__gnu_objc_personality_sj0"
! 				      : "__gnu_objc_personality_v0");
        default_init_unwind_resume_libfunc ();
        using_eh_for_cleanups ();
      }
  #endif
  }
*************** objc_begin_try_stmt (location_t try_locu
*** 3824,3830 ****
    c->end_try_locus = input_location;
    cur_try_context = c;
  
!   objc_init_exceptions ();
  
    if (flag_objc_sjlj_exceptions)
      objc_mark_locals_volatile (NULL);
--- 3814,3827 ----
    c->end_try_locus = input_location;
    cur_try_context = c;
  
!   if (flag_objc_sjlj_exceptions)
!     {
!       /* On Darwin, ObjC exceptions require a sufficiently recent
! 	 version of the runtime, so the user must ask for them explicitly.  */
!       if (!flag_objc_exceptions)
! 	warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
! 		 "exception syntax");
!     }
  
    if (flag_objc_sjlj_exceptions)
      objc_mark_locals_volatile (NULL);
*************** objc_build_throw_stmt (location_t loc, t
*** 3973,3979 ****
  {
    tree args;
  
!   objc_init_exceptions ();
  
    if (throw_expr == NULL)
      {
--- 3970,3983 ----
  {
    tree args;
  
!   if (flag_objc_sjlj_exceptions)
!     {
!       /* On Darwin, ObjC exceptions require a sufficiently recent
! 	 version of the runtime, so the user must ask for them explicitly.  */
!       if (!flag_objc_exceptions)
! 	warning (0, "use %<-fobjc-exceptions%> to enable Objective-C "
! 		 "exception syntax");
!     }
  
    if (throw_expr == NULL)
      {
Index: gcc/c-decl.c
===================================================================
*** gcc/c-decl.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/c-decl.c	2009-09-10 14:18:42.000000000 +0200
*************** tree pending_invalid_xref;
*** 92,100 ****
  /* File and line to appear in the eventual error message.  */
  location_t pending_invalid_xref_location;
  
- /* True means we've initialized exception handling.  */
- bool c_eh_initialized_p;
- 
  /* The file and line that the prototype came from if this is an
     old-style definition; used for diagnostics in
     store_parm_decls_oldstyle.  */
--- 92,97 ----
*************** merge_decls (tree newdecl, tree olddecl,
*** 2365,2371 ****
      TREE_USED (olddecl) = 1;
  
    /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
!      But preserve OLDDECL's DECL_UID and DECL_CONTEXT.  */
    {
      unsigned olddecl_uid = DECL_UID (olddecl);
      tree olddecl_context = DECL_CONTEXT (olddecl);
--- 2362,2369 ----
      TREE_USED (olddecl) = 1;
  
    /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
!      But preserve OLDDECL's DECL_UID, DECL_CONTEXT and
!      DECL_ARGUMENTS (if appropriate).  */
    {
      unsigned olddecl_uid = DECL_UID (olddecl);
      tree olddecl_context = DECL_CONTEXT (olddecl);
*************** start_decl (struct c_declarator *declara
*** 4048,4061 ****
  void
  c_maybe_initialize_eh (void)
  {
    if (!flag_exceptions || c_eh_initialized_p)
      return;
  
    c_eh_initialized_p = true;
!   eh_personality_libfunc
!     = init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 			? "__gcc_personality_sj0"
! 			: "__gcc_personality_v0");
    default_init_unwind_resume_libfunc ();
    using_eh_for_cleanups ();
  }
--- 4046,4062 ----
  void
  c_maybe_initialize_eh (void)
  {
+   static bool c_eh_initialized_p = false;
+ 
    if (!flag_exceptions || c_eh_initialized_p)
      return;
  
    c_eh_initialized_p = true;
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gcc_personality_sj0"
! 				  : "__gcc_personality_v0");
! 
    default_init_unwind_resume_libfunc ();
    using_eh_for_cleanups ();
  }
*************** finish_decl (tree decl, location_t init_
*** 4360,4368 ****
  	  TREE_USED (decl) = 1;
  	  TREE_USED (cleanup_decl) = 1;
  
- 	  /* Initialize EH, if we've been told to do so.  */
- 	  c_maybe_initialize_eh ();
- 
  	  push_cleanup (decl, cleanup, false);
  	}
      }
--- 4361,4366 ----
Index: gcc/c-parser.c
===================================================================
*** gcc/c-parser.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/c-parser.c	2009-09-10 14:18:42.000000000 +0200
*************** c_parser_omp_construct (c_parser *parser
*** 8489,8500 ****
    p_kind = c_parser_peek_token (parser)->pragma_kind;
    c_parser_consume_pragma (parser);
  
-   /* For all constructs below except #pragma omp atomic
-      MUST_NOT_THROW catch handlers are needed when exceptions
-      are enabled.  */
-   if (p_kind != PRAGMA_OMP_ATOMIC)
-     c_maybe_initialize_eh ();
- 
    switch (p_kind)
      {
      case PRAGMA_OMP_ATOMIC:
--- 8489,8494 ----
*************** c_parse_file (void)
*** 8607,8612 ****
--- 8601,8609 ----
    the_parser = GGC_NEW (c_parser);
    *the_parser = tparser;
  
+   /* Initialize EH, if we've been told to do so.  */
+   lang_hooks.init_eh ();
+ 
    c_parser_translation_unit (the_parser);
    the_parser = NULL;
  }
Index: gcc/c-lang.c
===================================================================
*** gcc/c-lang.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/c-lang.c	2009-09-10 14:18:42.000000000 +0200
*************** enum c_language_kind c_language = clk_c;
*** 44,49 ****
--- 44,51 ----
  #define LANG_HOOKS_NAME "GNU C"
  #undef LANG_HOOKS_INIT
  #define LANG_HOOKS_INIT c_objc_common_init
+ #undef LANG_HOOKS_INIT_EH
+ #define LANG_HOOKS_INIT_EH c_maybe_initialize_eh
  
  /* Each front end provides its own lang hook initializer.  */
  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Index: gcc/langhooks-def.h
===================================================================
*** gcc/langhooks-def.h.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/langhooks-def.h	2009-09-10 14:18:42.000000000 +0200
*************** extern void lhd_do_nothing (void);
*** 40,45 ****
--- 40,46 ----
  extern void lhd_do_nothing_t (tree);
  extern void lhd_do_nothing_i (int);
  extern void lhd_do_nothing_f (struct function *);
+ extern tree lhd_pass_through_t (tree);
  extern bool lhd_post_options (const char **);
  extern alias_set_type lhd_get_alias_set (tree);
  extern tree lhd_return_null_tree_v (void);
*************** extern void lhd_omp_firstprivatize_type_
*** 107,112 ****
--- 108,115 ----
  #define LANG_HOOKS_EXPR_TO_DECL		lhd_expr_to_decl
  #define LANG_HOOKS_TO_TARGET_CHARSET	lhd_to_target_charset
  #define LANG_HOOKS_INIT_TS		lhd_do_nothing
+ #define LANG_HOOKS_INIT_EH		NULL
+ #define LANG_HOOKS_EH_RUNTIME_TYPE	lhd_pass_through_t
  
  /* Attribute hooks.  */
  #define LANG_HOOKS_ATTRIBUTE_TABLE		NULL
*************** extern tree lhd_make_node (enum tree_cod
*** 271,276 ****
--- 274,281 ----
    LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \
    LANG_HOOKS_INIT_TS,          \
    LANG_HOOKS_EXPR_TO_DECL, \
+   LANG_HOOKS_INIT_EH, \
+   LANG_HOOKS_EH_RUNTIME_TYPE, \
  }
  
  #endif /* GCC_LANG_HOOKS_DEF_H */
Index: gcc/langhooks.h
===================================================================
*** gcc/langhooks.h.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/langhooks.h	2009-09-10 14:18:42.000000000 +0200
*************** struct lang_hooks
*** 414,419 ****
--- 414,425 ----
       if in the process TREE_CONSTANT or TREE_SIDE_EFFECTS need updating.  */
    tree (*expr_to_decl) (tree expr, bool *tc, bool *se);
  
+   /* Called to initialize the exception handing personality.  */
+   void (*init_eh) (void);
+ 
+   /* Map a type to a runtime object to match type.  */
+   tree (*eh_runtime_type) (tree);
+ 
    /* Whenever you add entries here, make sure you adjust langhooks-def.h
       and langhooks.c accordingly.  */
  };
Index: gcc/objc/objc-act.h
===================================================================
*** gcc/objc/objc-act.h.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/objc/objc-act.h	2009-09-10 14:18:42.000000000 +0200
*************** const char *objc_printable_name (tree, i
*** 32,37 ****
--- 32,39 ----
  void objc_finish_file (void);
  tree objc_fold_obj_type_ref (tree, tree);
  int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
+ void objc_init_exceptions (void);
+ tree objc_eh_runtime_type (tree);
  
  /* NB: The remaining public functions are prototyped in c-common.h, for the
     benefit of stub-objc.c and objc-act.c.  */
Index: gcc/objc/objc-lang.c
===================================================================
*** gcc/objc/objc-lang.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/objc/objc-lang.c	2009-09-10 14:18:42.000000000 +0200
*************** static void objc_init_ts (void);
*** 50,55 ****
--- 50,62 ----
  #define LANG_HOOKS_GIMPLIFY_EXPR objc_gimplify_expr
  #undef LANG_HOOKS_INIT_TS
  #define LANG_HOOKS_INIT_TS objc_init_ts
+ #undef LANG_HOOKS_INIT_EH
+ #define LANG_HOOKS_INIT_EH objc_init_exceptions
+ 
+ #ifndef OBJCPLUS
+ #undef LANG_HOOKS_EH_RUNTIME_TYPE
+ #define LANG_HOOKS_EH_RUNTIME_TYPE objc_eh_runtime_type
+ #endif
  
  /* Each front end provides its own lang hook initializer.  */
  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Index: gcc/ada/gcc-interface/misc.c
===================================================================
*** gcc/ada/gcc-interface/misc.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/ada/gcc-interface/misc.c	2009-09-10 14:18:42.000000000 +0200
*************** gnat_init_gcc_eh (void)
*** 431,441 ****
       right exception regions.  */
    using_eh_for_cleanups ();
  
!   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 					     ? "__gnat_eh_personality_sj"
! 					     : "__gnat_eh_personality");
    lang_eh_type_covers = gnat_eh_type_covers;
-   lang_eh_runtime_type = gnat_return_tree;
    default_init_unwind_resume_libfunc ();
  
    /* Turn on -fexceptions and -fnon-call-exceptions. The first one triggers
--- 431,442 ----
       right exception regions.  */
    using_eh_for_cleanups ();
  
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gnat_eh_personality_sj"
! 				  : "__gnat_eh_personality");
! 
    lang_eh_type_covers = gnat_eh_type_covers;
    default_init_unwind_resume_libfunc ();
  
    /* Turn on -fexceptions and -fnon-call-exceptions. The first one triggers
Index: gcc/cp/cp-lang.c
===================================================================
*** gcc/cp/cp-lang.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/cp/cp-lang.c	2009-09-10 14:18:42.000000000 +0200
*************** static enum classify_record cp_classify_
*** 71,76 ****
--- 71,78 ----
  #define LANG_HOOKS_FOLD_OBJ_TYPE_REF cp_fold_obj_type_ref
  #undef LANG_HOOKS_INIT_TS
  #define LANG_HOOKS_INIT_TS cp_init_ts
+ #undef LANG_HOOKS_EH_RUNTIME_TYPE
+ #define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
  
  /* Each front end provides its own lang hook initializer.  */
  struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
Index: gcc/cp/except.c
===================================================================
*** gcc/cp/except.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/cp/except.c	2009-09-10 14:18:42.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 43,49 ****
  
  static void push_eh_cleanup (tree);
  static tree prepare_eh_type (tree);
- static tree build_eh_type_type (tree);
  static tree do_begin_catch (void);
  static int dtor_nothrow (tree);
  static tree do_end_catch (tree);
--- 43,48 ----
*************** init_exception_processing (void)
*** 78,92 ****
    call_unexpected_node
      = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
  
!   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 					     ? "__gxx_personality_sj0"
! 					     : "__gxx_personality_v0");
    if (targetm.arm_eabi_unwinder)
      unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
    else
      default_init_unwind_resume_libfunc ();
  
-   lang_eh_runtime_type = build_eh_type_type;
    lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
  }
  
--- 77,92 ----
    call_unexpected_node
      = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp);
  
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gxx_personality_sj0"
! 				  : "__gxx_personality_v0");
! 
    if (targetm.arm_eabi_unwinder)
      unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
    else
      default_init_unwind_resume_libfunc ();
  
    lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
  }
  
*************** eh_type_info (tree type)
*** 143,149 ****
  /* Build the address of a typeinfo decl for use in the runtime
     matching field of the exception model.  */
  
! static tree
  build_eh_type_type (tree type)
  {
    tree exp = eh_type_info (type);
--- 143,149 ----
  /* Build the address of a typeinfo decl for use in the runtime
     matching field of the exception model.  */
  
! tree
  build_eh_type_type (tree type)
  {
    tree exp = eh_type_info (type);
*************** decl_is_java_type (tree decl, int err)
*** 313,319 ****
  /* Select the personality routine to be used for exception handling,
     or issue an error if we need two different ones in the same
     translation unit.
!    ??? At present eh_personality_libfunc is set to
     __gxx_personality_(sj|v)0 in init_exception_processing - should it
     be done here instead?  */
  void
--- 313,319 ----
  /* Select the personality routine to be used for exception handling,
     or issue an error if we need two different ones in the same
     translation unit.
!    ??? At present eh_personality_decl is set to
     __gxx_personality_(sj|v)0 in init_exception_processing - should it
     be done here instead?  */
  void
*************** choose_personality_routine (enum languag
*** 354,362 ****
      case lang_java:
        state = chose_java;
        terminate_node = built_in_decls [BUILT_IN_ABORT];
!       eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
! 						 ? "__gcj_personality_sj0"
! 						 : "__gcj_personality_v0");
        break;
  
      default:
--- 354,363 ----
      case lang_java:
        state = chose_java;
        terminate_node = built_in_decls [BUILT_IN_ABORT];
!       eh_personality_decl
! 	= build_personality_function (USING_SJLJ_EXCEPTIONS
! 				      ? "__gcj_personality_sj0"
! 				      : "__gcj_personality_v0");
        break;
  
      default:
Index: gcc/except.c
===================================================================
*** gcc/except.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/except.c	2009-09-10 16:20:09.000000000 +0200
*************** gimple (*lang_protect_cleanup_actions) (
*** 92,100 ****
  /* Return true if type A catches type B.  */
  int (*lang_eh_type_covers) (tree a, tree b);
  
- /* Map a type to a runtime object to match type.  */
- tree (*lang_eh_runtime_type) (tree);
- 
  /* A hash table of label to region number.  */
  
  struct GTY(()) ehl_map_entry {
--- 92,97 ----
*************** add_type_for_runtime (tree type)
*** 1696,1702 ****
  					    TREE_HASH (type), INSERT);
    if (*slot == NULL)
      {
!       tree runtime = (*lang_eh_runtime_type) (type);
        *slot = tree_cons (type, runtime, NULL_TREE);
      }
  }
--- 1693,1699 ----
  					    TREE_HASH (type), INSERT);
    if (*slot == NULL)
      {
!       tree runtime = lang_hooks.eh_runtime_type (type);
        *slot = tree_cons (type, runtime, NULL_TREE);
      }
  }
*************** sjlj_emit_function_enter (rtx dispatch_l
*** 2424,2429 ****
--- 2421,2427 ----
  {
    rtx fn_begin, fc, mem, seq;
    bool fn_begin_outside_block;
+   rtx personality = get_personality_function (current_function_decl);
  
    fc = crtl->eh.sjlj_fc;
  
*************** sjlj_emit_function_enter (rtx dispatch_l
*** 2432,2440 ****
    /* We're storing this libcall's address into memory instead of
       calling it directly.  Thus, we must call assemble_external_libcall
       here, as we can not depend on emit_library_call to do it for us.  */
!   assemble_external_libcall (eh_personality_libfunc);
    mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
!   emit_move_insn (mem, eh_personality_libfunc);
  
    mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
    if (crtl->uses_eh_lsda)
--- 2430,2438 ----
    /* We're storing this libcall's address into memory instead of
       calling it directly.  Thus, we must call assemble_external_libcall
       here, as we can not depend on emit_library_call to do it for us.  */
!   assemble_external_libcall (personality);
    mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
!   emit_move_insn (mem, personality);
  
    mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
    if (crtl->uses_eh_lsda)
*************** output_ttype (tree type, int tt_format,
*** 4394,4400 ****
  
  static void
  output_one_function_exception_table (const char * ARG_UNUSED (fnname),
! 				     int section)
  {
    int tt_format, cs_format, lp_format, i, n;
  #ifdef HAVE_AS_LEB128
--- 4392,4398 ----
  
  static void
  output_one_function_exception_table (const char * ARG_UNUSED (fnname),
! 				     int section, rtx ARG_UNUSED (personality))
  {
    int tt_format, cs_format, lp_format, i, n;
  #ifdef HAVE_AS_LEB128
*************** output_one_function_exception_table (con
*** 4410,4416 ****
  #ifdef TARGET_UNWIND_INFO
    /* TODO: Move this into target file.  */
    fputs ("\t.personality\t", asm_out_file);
!   output_addr_const (asm_out_file, eh_personality_libfunc);
    fputs ("\n\t.handlerdata\n", asm_out_file);
    /* Note that varasm still thinks we're in the function's code section.
       The ".endp" directive that will immediately follow will take us back.  */
--- 4408,4414 ----
  #ifdef TARGET_UNWIND_INFO
    /* TODO: Move this into target file.  */
    fputs ("\t.personality\t", asm_out_file);
!   output_addr_const (asm_out_file, personality);
    fputs ("\n\t.handlerdata\n", asm_out_file);
    /* Note that varasm still thinks we're in the function's code section.
       The ".endp" directive that will immediately follow will take us back.  */
*************** output_one_function_exception_table (con
*** 4580,4595 ****
  void
  output_function_exception_table (const char * ARG_UNUSED (fnname))
  {
    /* Not all functions need anything.  */
    if (! crtl->uses_eh_lsda)
      return;
  
!   if (eh_personality_libfunc)
!     assemble_external_libcall (eh_personality_libfunc);
  
!   output_one_function_exception_table (fnname, 0);
    if (crtl->eh.call_site_record[1] != NULL)
!     output_one_function_exception_table (fnname, 1);
  
    switch_to_section (current_function_section ());
  }
--- 4578,4595 ----
  void
  output_function_exception_table (const char * ARG_UNUSED (fnname))
  {
+   rtx personality = get_personality_function (current_function_decl);
+ 
    /* Not all functions need anything.  */
    if (! crtl->uses_eh_lsda)
      return;
  
!   if (personality)
!     assemble_external_libcall (personality);
  
!   output_one_function_exception_table (fnname, 0, personality);
    if (crtl->eh.call_site_record[1] != NULL)
!     output_one_function_exception_table (fnname, 1, personality);
  
    switch_to_section (current_function_section ());
  }
*************** get_eh_throw_stmt_table (struct function
*** 4606,4611 ****
--- 4606,4676 ----
    return fun->eh->throw_stmt_table;
  }
  
+ /* Return true if the function deeds a EH personality function.  */
+ 
+ bool
+ function_needs_eh_personality (struct function *fn)
+ {
+   struct eh_region_d *i;
+   int depth = 0;
+ 
+   i = fn->eh->region_tree;
+   if (!i)
+     return false;
+ 
+   while (1)
+     {
+       switch (i->type)
+ 	{
+ 	case ERT_TRY:
+ 	case ERT_THROW:
+ 	  /* Do not need a EH personality function.  */
+ 	  break;
+ 
+ 	case ERT_MUST_NOT_THROW:
+ 	case ERT_CLEANUP:
+ 	  /* Ok with the default C EH personality.  */
+ 	  break;
+ 
+ 	case ERT_CATCH:
+ 	  /* An empty type list is ok with the default C EH personality.  */
+ 	  if (i->u.eh_catch.type_list)
+ 	    return true;
+ 	  break;
+ 
+ 	case ERT_ALLOWED_EXCEPTIONS:
+ 	  /* An empty type list is ok with the default C EH personality.  */
+ 	  if (i->u.allowed.type_list)
+ 	    return true;
+ 	  break;
+ 
+ 	case ERT_UNKNOWN:
+ 	  return true;
+ 	}
+       /* If there are sub-regions, process them.  */
+       if (i->inner)
+ 	i = i->inner, depth++;
+       /* If there are peers, process them.  */
+       else if (i->next_peer)
+ 	i = i->next_peer;
+       /* Otherwise, step back up the tree to the next peer.  */
+       else
+ 	{
+ 	  do
+ 	    {
+ 	      i = i->outer;
+ 	      depth--;
+ 	      if (i == NULL)
+ 		return false;
+ 	    }
+ 	  while (i->next_peer == NULL);
+ 	  i = i->next_peer;
+ 	}
+     }
+ 
+   return false;
+ }
+ 
  /* Dump EH information to OUT.  */
  
  void
Index: gcc/except.h
===================================================================
*** gcc/except.h.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/except.h	2009-09-10 14:50:26.000000000 +0200
*************** extern gimple (*lang_protect_cleanup_act
*** 217,225 ****
  /* Return true if type A catches type B.  */
  extern int (*lang_eh_type_covers) (tree a, tree b);
  
- /* Map a type to a runtime object to match type.  */
- extern tree (*lang_eh_runtime_type) (tree);
- 
  
  /* Just because the user configured --with-sjlj-exceptions=no doesn't
     mean that we can use call frame exceptions.  Detect that the target
--- 217,222 ----
*************** extern int num_eh_regions (void);
*** 277,279 ****
--- 274,277 ----
  extern bitmap must_not_throw_labels (void);
  extern struct eh_region_d *redirect_eh_edge_to_label (struct edge_def *, tree, bool, bool, int);
  extern int get_next_region_sharing_label (int);
+ extern bool function_needs_eh_personality (struct function *);
Index: gcc/java/decl.c
===================================================================
*** gcc/java/decl.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/java/decl.c	2009-09-10 14:18:42.000000000 +0200
*************** create_primitive_vtable (const char *nam
*** 510,521 ****
    return r;
  }
  
- static tree
- do_nothing (tree t)
- {
-   return t;
- }
- 
  /* Parse the version string and compute the ABI version number.  */
  static void
  parse_version (void)
--- 510,515 ----
*************** java_init_decl_processing (void)
*** 1195,1210 ****
  			    0, NOT_BUILT_IN, NULL, NULL_TREE);
  
    /* Initialize variables for except.c.  */
!   eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS
!                                              ? "__gcj_personality_sj0"
!                                              : "__gcj_personality_v0");
    if (targetm.arm_eabi_unwinder)
      unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
    else
      default_init_unwind_resume_libfunc ();
  
-   lang_eh_runtime_type = do_nothing;
- 
    initialize_builtins ();
    soft_fmod_node = built_in_decls[BUILT_IN_FMOD];
  
--- 1189,1205 ----
  			    0, NOT_BUILT_IN, NULL, NULL_TREE);
  
    /* Initialize variables for except.c.  */
! 
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gcj_personality_sj0"
! 				  : "__gcj_personality_v0");
! 
    if (targetm.arm_eabi_unwinder)
      unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
    else
      default_init_unwind_resume_libfunc ();
  
    initialize_builtins ();
    soft_fmod_node = built_in_decls[BUILT_IN_FMOD];
  
Index: gcc/langhooks.c
===================================================================
*** gcc/langhooks.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/langhooks.c	2009-09-10 14:18:42.000000000 +0200
*************** lhd_do_nothing_t (tree ARG_UNUSED (t))
*** 53,58 ****
--- 53,65 ----
  {
  }
  
+ /* Pass through (tree).  */
+ tree
+ lhd_pass_through_t (tree t)
+ {
+   return t;
+ }
+ 
  /* Do nothing (int).  */
  
  void
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/cp/cp-tree.h	2009-09-10 14:18:42.000000000 +0200
*************** extern void choose_personality_routine
*** 4521,4526 ****
--- 4521,4527 ----
  extern tree eh_type_info			(tree);
  extern tree begin_eh_spec_block			(void);
  extern void finish_eh_spec_block		(tree, tree);
+ extern tree build_eh_type_type			(tree);
  
  /* in expr.c */
  extern tree cplus_expand_constant		(tree);
Index: gcc/libfuncs.h
===================================================================
*** gcc/libfuncs.h.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/libfuncs.h	2009-09-10 14:18:42.000000000 +0200
*************** enum libfunc_index
*** 31,37 ****
    LTI_setbits,
  
    LTI_unwind_resume,
-   LTI_eh_personality,
    LTI_setjmp,
    LTI_longjmp,
    LTI_unwind_sjlj_register,
--- 31,36 ----
*************** extern GTY(()) rtx libfunc_table[LTI_MAX
*** 61,67 ****
  #define setbits_libfunc	(libfunc_table[LTI_setbits])
  
  #define unwind_resume_libfunc	(libfunc_table[LTI_unwind_resume])
- #define eh_personality_libfunc	(libfunc_table[LTI_eh_personality])
  #define setjmp_libfunc	(libfunc_table[LTI_setjmp])
  #define longjmp_libfunc	(libfunc_table[LTI_longjmp])
  #define unwind_sjlj_register_libfunc (libfunc_table[LTI_unwind_sjlj_register])
--- 60,65 ----
Index: gcc/optabs.c
===================================================================
*** gcc/optabs.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/optabs.c	2009-09-10 14:18:42.000000000 +0200
*************** libfunc_decl_eq (const void *entry1, con
*** 6023,6028 ****
--- 6023,6050 ----
    return DECL_NAME ((const_tree) entry1) == (const_tree) entry2;
  }
  
+ /* Build a decl for a libfunc named NAME. */
+ 
+ tree
+ build_libfunc_function (const char *name)
+ {
+   tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
+ 			  get_identifier (name),
+                           build_function_type (integer_type_node, NULL_TREE));
+   /* ??? We don't have any type information except for this is
+      a function.  Pretend this is "int foo()".  */
+   DECL_ARTIFICIAL (decl) = 1;
+   DECL_EXTERNAL (decl) = 1;
+   TREE_PUBLIC (decl) = 1;
+   gcc_assert (DECL_ASSEMBLER_NAME (decl));
+ 
+   /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
+      are the flags assigned by targetm.encode_section_info.  */
+   SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
+ 
+   return decl;
+ }
+ 
  rtx
  init_one_libfunc (const char *name)
  {
*************** init_one_libfunc (const char *name)
*** 6043,6061 ****
      {
        /* Create a new decl, so that it can be passed to
  	 targetm.encode_section_info.  */
!       /* ??? We don't have any type information except for this is
! 	 a function.  Pretend this is "int foo()".  */
!       decl = build_decl (UNKNOWN_LOCATION,
! 			 FUNCTION_DECL, get_identifier (name),
! 			 build_function_type (integer_type_node, NULL_TREE));
!       DECL_ARTIFICIAL (decl) = 1;
!       DECL_EXTERNAL (decl) = 1;
!       TREE_PUBLIC (decl) = 1;
! 
!       /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left with
! 	 are the flags assigned by targetm.encode_section_info.  */
!       SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
! 
        *slot = decl;
      }
    return XEXP (DECL_RTL (decl), 0);
--- 6065,6071 ----
      {
        /* Create a new decl, so that it can be passed to
  	 targetm.encode_section_info.  */
!       decl = build_libfunc_function (name);
        *slot = decl;
      }
    return XEXP (DECL_RTL (decl), 0);
Index: gcc/tree.h
===================================================================
*** gcc/tree.h.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/tree.h	2009-09-10 14:18:42.000000000 +0200
*************** struct GTY(()) tree_decl_minimal {
*** 2538,2543 ****
--- 2538,2546 ----
  #define DECL_DEBUG_EXPR_IS_FROM(NODE) \
    (DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from)
  
+ #define DECL_FUNCTION_PERSONALITY(NODE) \
+   (FUNCTION_DECL_CHECK (NODE)->function_decl.personality)
+ 
  /* Nonzero for a given ..._DECL node means that the name of this node should
     be ignored for symbolic debug purposes.  */
  #define DECL_IGNORED_P(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.ignored_flag)
*************** struct GTY(()) tree_function_decl {
*** 3188,3193 ****
--- 3191,3199 ----
  
    struct function *f;
  
+   /* The personality function. Used for stack unwinding. */
+   tree personality;
+ 
    /* Function specific options that are used by this function.  */
    tree function_specific_target;	/* target options */
    tree function_specific_optimization;	/* optimization options */
*************** extern int pedantic_lvalues;
*** 4557,4562 ****
--- 4563,4571 ----
  
  extern GTY(()) tree current_function_decl;
  
+ /* The eh personally function that this FE wants to use. */
+ extern GTY(()) tree eh_personality_decl;
+ 
  /* Nonzero means a FUNC_BEGIN label was emitted.  */
  extern GTY(()) const char * current_function_func_begin_label;
  
Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/toplev.c	2009-09-10 14:18:42.000000000 +0200
*************** int optimize_size = 0;
*** 202,207 ****
--- 202,210 ----
     or 0 if between functions.  */
  tree current_function_decl;
  
+ /* The EH personality function that this FE wants to use. */
+ tree eh_personality_decl;
+ 
  /* Set to the FUNC_BEGIN label of the current function, or NULL
     if none.  */
  const char * current_function_func_begin_label;
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/dwarf2out.c	2009-09-10 14:18:42.000000000 +0200
*************** static GTY(()) section *debug_str_sectio
*** 216,221 ****
--- 216,225 ----
  static GTY(()) section *debug_ranges_section;
  static GTY(()) section *debug_frame_section;
  
+ /* Personality decl of current unit.  Used only when assembler does not support
+    personality CFI.  */
+ static GTY(()) rtx current_unit_personality;
+ 
  /* How to start an assembler comment.  */
  #ifndef ASM_COMMENT_START
  #define ASM_COMMENT_START ";#"
*************** output_call_frame_info (int for_eh)
*** 3599,3604 ****
--- 3603,3609 ----
    int per_encoding = DW_EH_PE_absptr;
    int lsda_encoding = DW_EH_PE_absptr;
    int return_reg;
+   rtx personality = NULL;
    int dw_cie_version;
  
    /* Don't emit a CIE if there won't be any FDEs.  */
*************** output_call_frame_info (int for_eh)
*** 3684,3689 ****
--- 3689,3696 ----
  
    augmentation[0] = 0;
    augmentation_size = 0;
+ 
+   personality = current_unit_personality;
    if (for_eh)
      {
        char *p;
*************** output_call_frame_info (int for_eh)
*** 3703,3713 ****
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
        p = augmentation + 1;
!       if (eh_personality_libfunc)
  	{
  	  *p++ = 'P';
  	  augmentation_size += 1 + size_of_encoded_value (per_encoding);
! 	  assemble_external_libcall (eh_personality_libfunc);
  	}
        if (any_lsda_needed)
  	{
--- 3710,3720 ----
        lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
  
        p = augmentation + 1;
!       if (personality)
  	{
  	  *p++ = 'P';
  	  augmentation_size += 1 + size_of_encoded_value (per_encoding);
! 	  assemble_external_libcall (personality);
  	}
        if (any_lsda_needed)
  	{
*************** output_call_frame_info (int for_eh)
*** 3726,3732 ****
  	}
  
        /* Ug.  Some platforms can't do unaligned dynamic relocations at all.  */
!       if (eh_personality_libfunc && per_encoding == DW_EH_PE_aligned)
  	{
  	  int offset = (  4		/* Length */
  			+ 4		/* CIE Id */
--- 3733,3739 ----
  	}
  
        /* Ug.  Some platforms can't do unaligned dynamic relocations at all.  */
!       if (personality && per_encoding == DW_EH_PE_aligned)
  	{
  	  int offset = (  4		/* Length */
  			+ 4		/* CIE Id */
*************** output_call_frame_info (int for_eh)
*** 3760,3771 ****
    if (augmentation[0])
      {
        dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size");
!       if (eh_personality_libfunc)
  	{
  	  dw2_asm_output_data (1, per_encoding, "Personality (%s)",
  			       eh_data_format_name (per_encoding));
  	  dw2_asm_output_encoded_addr_rtx (per_encoding,
! 					   eh_personality_libfunc,
  					   true, NULL);
  	}
  
--- 3767,3778 ----
    if (augmentation[0])
      {
        dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size");
!       if (personality)
  	{
  	  dw2_asm_output_data (1, per_encoding, "Personality (%s)",
  			       eh_data_format_name (per_encoding));
  	  dw2_asm_output_encoded_addr_rtx (per_encoding,
! 					   personality,
  					   true, NULL);
  	}
  
*************** dwarf2out_do_cfi_startproc (bool second)
*** 3824,3836 ****
  {
    int enc;
    rtx ref;
  
    fprintf (asm_out_file, "\t.cfi_startproc\n");
  
!   if (eh_personality_libfunc)
      {
        enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
!       ref = eh_personality_libfunc;
  
        /* ??? The GAS support isn't entirely consistent.  We have to
  	 handle indirect support ourselves, but PC-relative is done
--- 3831,3844 ----
  {
    int enc;
    rtx ref;
+   rtx personality = get_personality_function (current_function_decl);
  
    fprintf (asm_out_file, "\t.cfi_startproc\n");
  
!   if (personality)
      {
        enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
!       ref = personality;
  
        /* ??? The GAS support isn't entirely consistent.  We have to
  	 handle indirect support ourselves, but PC-relative is done
*************** dwarf2out_begin_prologue (unsigned int l
*** 3873,3878 ****
--- 3881,3887 ----
    char label[MAX_ARTIFICIAL_LABEL_BYTES];
    char * dup_label;
    dw_fde_ref fde;
+   rtx personality;
    section *fnsec;
  
    current_function_func_begin_label = NULL;
*************** dwarf2out_begin_prologue (unsigned int l
*** 3967,3974 ****
--- 3976,3992 ----
      dwarf2out_source_line (line, file, 0, true);
  #endif
  
+   personality = get_personality_function (current_function_decl);
    if (dwarf2out_do_cfi_asm ())
      dwarf2out_do_cfi_startproc (false);
+   else
+     {
+       if (!current_unit_personality || current_unit_personality == personality)
+         current_unit_personality = personality;
+       else
+ 	sorry ("Multiple EH personalities are supported only with assemblers "
+ 	       "supporting .cfi.personality directive.");
+     }
  }
  
  /* Output a marker (i.e. a label) for the absolute end of the generated code
Index: gcc/expr.h
===================================================================
*** gcc/expr.h.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/expr.h	2009-09-10 16:28:30.000000000 +0200
*************** extern void init_all_optabs (void);
*** 814,819 ****
--- 814,832 ----
  extern rtx init_one_libfunc (const char *);
  extern rtx set_user_assembler_libfunc (const char *, const char *);
  
+ /* Build a decl for a libfunc named NAME. */
+ extern tree build_libfunc_function (const char *);
+ 
+ /* Build a decl for a personality function named NAME. */
+ static inline tree
+ build_personality_function (const char *name)
+ {
+   return build_libfunc_function (name);
+ }
+ 
+ /* Get the personality libfunc for a function decl.  */
+ rtx get_personality_function (tree);
+ 
  extern int vector_mode_valid_p (enum machine_mode);
  
  #endif /* GCC_EXPR_H */
Index: gcc/fortran/f95-lang.c
===================================================================
*** gcc/fortran/f95-lang.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/fortran/f95-lang.c	2009-09-10 14:18:42.000000000 +0200
*************** gfc_maybe_initialize_eh (void)
*** 1155,1164 ****
      return;
  
    gfc_eh_initialized_p = true;
!   eh_personality_libfunc
!     = init_one_libfunc (USING_SJLJ_EXCEPTIONS
!                        ? "__gcc_personality_sj0"
!                        : "__gcc_personality_v0");
    default_init_unwind_resume_libfunc ();
    using_eh_for_cleanups ();
  }
--- 1155,1164 ----
      return;
  
    gfc_eh_initialized_p = true;
!   eh_personality_decl
!     = build_personality_function (USING_SJLJ_EXCEPTIONS
! 				  ? "__gcc_personality_sj0"
! 				  : "__gcc_personality_v0");
    default_init_unwind_resume_libfunc ();
    using_eh_for_cleanups ();
  }
Index: gcc/c-tree.h
===================================================================
*** gcc/c-tree.h.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/c-tree.h	2009-09-10 14:18:42.000000000 +0200
*************** extern int system_header_p;
*** 589,597 ****
  
  extern bool c_override_global_bindings_to_false;
  
- /* True means we've initialized exception handling.  */
- extern bool c_eh_initialized_p;
- 
  /* In c-decl.c */
  extern void c_finish_incomplete_decl (tree);
  extern void c_write_global_declarations (void);
--- 589,594 ----
Index: gcc/tree-eh.c
===================================================================
*** gcc/tree-eh.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/tree-eh.c	2009-09-10 15:11:52.000000000 +0200
*************** lower_eh_constructs (void)
*** 1939,1944 ****
--- 1939,1948 ----
    htab_delete (finally_tree);
  
    collect_eh_region_array ();
+ 
+   if (function_needs_eh_personality (cfun))
+     DECL_FUNCTION_PERSONALITY (current_function_decl) = eh_personality_decl;
+ 
    return 0;
  }
  
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c.orig	2009-09-10 13:40:45.000000000 +0200
--- gcc/tree-inline.c	2009-09-10 14:21:01.000000000 +0200
*************** tree_can_inline_p (struct cgraph_edge *e
*** 4999,5004 ****
--- 4999,5019 ----
    caller = e->caller->decl;
    callee = e->callee->decl;
  
+   /* We cannot inline a function that uses a different EH personality
+      than the caller.  Restrict inlining functions with either no EH
+      personality or calls with matching personality in the caller
+      and callee for now, that will not require personality changes
+      in the caller.  Everything more advanced needs to be taken into
+      account during the inline plan computation.  */
+   if (DECL_FUNCTION_PERSONALITY (callee)
+       && (DECL_FUNCTION_PERSONALITY (caller)
+ 	  != DECL_FUNCTION_PERSONALITY (callee)))
+     {
+       e->inline_failed = CIF_UNSPECIFIED;
+       gimple_call_set_cannot_inline (e->call_stmt, true);
+       return false;
+     }
+ 
    /* Allow the backend to decide if inlining is ok.  */
    if (!targetm.target_option.can_inline_p (caller, callee))
      {
Index: gcc/expr.c
===================================================================
*** gcc/expr.c.orig	2009-09-10 10:49:08.000000000 +0200
--- gcc/expr.c	2009-09-10 16:28:58.000000000 +0200
*************** const_vector_from_tree (tree exp)
*** 10214,10217 ****
--- 10214,10241 ----
  
    return gen_rtx_CONST_VECTOR (mode, v);
  }
+ 
+ 
+ /* Extracts the personality function of DECL and returns the corresponding
+    libfunc.  */
+ 
+ rtx
+ get_personality_function (tree decl)
+ {
+   tree personality = DECL_FUNCTION_PERSONALITY (decl);
+   tree name;
+ 
+   if (!personality && !eh_personality_decl)
+     return NULL;
+ 
+   if (!personality)
+     return init_one_libfunc (USING_SJLJ_EXCEPTIONS
+ 			     ? "__gcc_personality_sj0"
+ 			     : "__gcc_personality_v0");
+ 
+   name = DECL_ASSEMBLER_NAME (personality);
+ 
+   return init_one_libfunc (IDENTIFIER_POINTER (name));
+ }
+ 
  #include "gt-expr.h"


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