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 Tue, 8 Sep 2009, Richard Guenther wrote:

> On Sat, 5 Sep 2009, Richard Henderson wrote:
> 
> > On 09/05/2009 10:24 AM, Richard Guenther wrote:
> > > > Also, I think you need to add something to prevent inlining of functions
> > > > that use different personality functions.
> > > 
> > > I don't think so.  The IL should be still in a state where the inlined
> > > pieces would simply inherit the callers personality.  But maybe I'm
> > > missing something?
> > 
> > You're missing that the personality functions have to deal with
> > the language's runtime types, as recorded in the catch type_list
> > and the allowed-exceptions type_list.
> > 
> > You can't expect the Ada personality to deal with C++ runtime types.
> 
> Hmm, ok.  So how about setting DECL_EH_PERSONALITY during eh-lowering
> and only for functions with a non-empty EH tree.  We then would
> disallow inlining functions with different non-NULL personality.
> 
> > > > Do you have a strategy for handling
> > > > 
> > > >    if (targetm.arm_eabi_unwinder)
> > > >      unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup");
> > > > 
> > > > since this function is only used for c++/java?
> > > 
> > > No.  Do you have something in mind?
> > 
> > The only thing I can think of is to record the fact that the
> > GIMPLE_TRY came from c++/java in the eh_region tree, which would
> > allow the RESX expander to emit the proper function for this
> > particular region.  It's not elegant, but it should work.
> 
> With your EH rewrite we could make this function explicit in the IL,
> can we?
> 
> > > I see the patch is somewhat incomplete (there's also
> > > lang_eh_runtime_type, but maybe we never call add_type_for_runtime
> > > after a frontend finishes - in which case this should have been
> > > a langhook?) - and in general the integration of EH aware and
> > > non-EH aware code with LTO still needs work and thought.
> > 
> > We do all the calls to add_type_for_runtime during
> > pass_lower_eh, right toward the beginning of compilation.
> > I'm pretty sure we don't need to do anything else with
> > that lang hook for LTO.
> 
> 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.

> How does that sound?

FYI the following two patches would implement the above (untested).

Richard.

2009-09-08  Richard Guenther  <rguenther@suse.de>

	* c-decl.c (finish_decl): Don't call c_maybe_initialize_eh.
        * c-parser.c (c_parser_omp_construct): Likewise.
	(c_parse_file): Call lang_hooks.init_eh.
	* except.h (lang_eh_runtime_type): Remove.
        * except.c (lang_eh_runtime_type): Remove.
	(add_type_for_runtime): Call lang_hooks.type_for_runtime instead.

	* 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.

	* c-lang.c (LANG_HOOKS_INIT_EH): Define.

	objc/
	* objc-act.c (objc_eh_runtime_type): Export.
	(objc_init_exceptions): Export.  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.
	* 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.

	ada/
	* gcc-interface/misc.c (gnat_init_gcc_eh): Do not set
	lang_eh_runtime_type.

Index: gcc/objc/objc-act.c
===================================================================
*** gcc/objc/objc-act.c.orig	2009-08-31 15:50:38.000000000 +0200
--- gcc/objc/objc-act.c	2009-09-08 12:29:56.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,3520 ****
      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
--- 3505,3512 ----
      return;
    done = true;
  
  #ifndef OBJCPLUS
!   if (!flag_objc_sjlj_exceptions)
      {
        c_eh_initialized_p = true;
        eh_personality_libfunc
*************** objc_init_exceptions (void)
*** 3523,3529 ****
  			    : "__gnu_objc_personality_v0");
        default_init_unwind_resume_libfunc ();
        using_eh_for_cleanups ();
-       lang_eh_runtime_type = objc_eh_runtime_type;
      }
  #endif
  }
--- 3515,3520 ----
*************** 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);
--- 3815,3828 ----
    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)
      {
--- 3971,3984 ----
  {
    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-08-31 15:50:38.000000000 +0200
--- gcc/c-decl.c	2009-09-08 12:18:56.000000000 +0200
*************** 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);
  	}
      }
--- 4360,4365 ----
Index: gcc/c-parser.c
===================================================================
*** gcc/c-parser.c.orig	2009-08-31 15:50:38.000000000 +0200
--- gcc/c-parser.c	2009-09-08 12:34:32.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-04 15:05:57.000000000 +0200
--- gcc/c-lang.c	2009-09-08 12:18:56.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-04 15:05:57.000000000 +0200
--- gcc/langhooks-def.h	2009-09-08 12:29:01.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-04 15:05:56.000000000 +0200
--- gcc/langhooks.h	2009-09-08 12:23:32.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-06-15 11:55:46.000000000 +0200
--- gcc/objc/objc-act.h	2009-09-08 12:31:39.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-04 15:05:40.000000000 +0200
--- gcc/objc/objc-lang.c	2009-09-08 12:31:09.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-04 15:05:52.000000000 +0200
--- gcc/ada/gcc-interface/misc.c	2009-09-08 12:32:31.000000000 +0200
*************** gnat_init_gcc_eh (void)
*** 435,441 ****
  					     ? "__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
--- 435,440 ----
Index: gcc/cp/cp-lang.c
===================================================================
*** gcc/cp/cp-lang.c.orig	2009-09-04 15:05:51.000000000 +0200
--- gcc/cp/cp-lang.c	2009-09-08 12:26:24.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-08-31 15:50:38.000000000 +0200
--- gcc/cp/except.c	2009-09-08 12:50:35.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)
*** 86,92 ****
    else
      default_init_unwind_resume_libfunc ();
  
-   lang_eh_runtime_type = build_eh_type_type;
    lang_protect_cleanup_actions = &cp_protect_cleanup_actions;
  }
  
--- 85,90 ----
*************** 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);
--- 141,147 ----
  /* 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);
Index: gcc/except.c
===================================================================
*** gcc/except.c.orig	2009-09-04 15:05:57.000000000 +0200
--- gcc/except.c	2009-09-08 12:23:57.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);
      }
  }
Index: gcc/except.h
===================================================================
*** gcc/except.h.orig	2009-09-04 15:05:57.000000000 +0200
--- gcc/except.h	2009-09-08 12:23:13.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 ----
Index: gcc/java/decl.c
===================================================================
*** gcc/java/decl.c.orig	2009-08-31 15:50:38.000000000 +0200
--- gcc/java/decl.c	2009-09-08 12:29:15.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)
*** 1203,1210 ****
    else
      default_init_unwind_resume_libfunc ();
  
-   lang_eh_runtime_type = do_nothing;
- 
    initialize_builtins ();
    soft_fmod_node = built_in_decls[BUILT_IN_FMOD];
  
--- 1197,1202 ----
Index: gcc/langhooks.c
===================================================================
*** gcc/langhooks.c.orig	2009-09-04 15:05:56.000000000 +0200
--- gcc/langhooks.c	2009-09-08 12:28:21.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-04 15:05:51.000000000 +0200
--- gcc/cp/cp-tree.h	2009-09-08 12:51:08.000000000 +0200
*************** extern void choose_personality_routine
*** 4522,4527 ****
--- 4522,4528 ----
  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);


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

	* c-decl.c (c_maybe_initialize_eh): Init eh_personality_decl
        instead of eh_personality_libfunc.
        (finish_decl): Don't call c_maybe_initialize_eh.
        * c-parser.c (c_parse_file): Call lang_hooks.init_eh.
        * dwarf2out.c (output_call_frame_info, dwarf2out_do_cfi_startproc,
	dwarf2out_begin_prologue): Use personality from current_function_decl.
        * except.c (sjlj_emit_function_enter, output_function_exception_table):
        Use personality from current_function_decl.
        * expr.h (build_personality_function, get_personality_function): New.
        * 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.c (make_node_stat):  Set DECL_FUNCTION_PERSONALITY.
        * tree.h (DECL_FUNCTION_PERSONALITY): New.
        (tree_function_decl): Add personality.
        (eh_personality_decl): New.

	* langhooks-def.h (LANG_HOOKS_INIT_EH): Define.
	(LANG_HOOKS_INITIALIZER): Adjust.
	* langhooks.h (struct lang_hooks): Add init_eh.
	* c-lang.c (LANG_HOOKS_INIT_EH): Define.

	objc/
	* objc-act.c (objc_init_exceptions): Export.  Move warning code ...
	(objc_begin_try_stmt): ... here
	(objc_build_throw_stmt): ... and here.
	* objc-act.h (objc_init_exceptions): Declare.
	* objc-lang.c (LANG_HOOKS_INIT_EH): Define.

	cp/
	* except.c (init_exception_processing, choose_personality_routine):
	Init eh_personality_decl instead of eh_personality_libfunc.

	java/
	* decl.c (java_init_decl_processing): Init eh_personality_decl
	instead of eh_personality_libfunc.

	ada/
	* gcc-interface/misc.c (gnat_init_gcc_eh): 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/java/decl.c
===================================================================
*** gcc/java/decl.c.orig	2009-09-08 15:27:29.000000000 +0200
--- gcc/java/decl.c	2009-09-08 15:27:39.000000000 +0200
*************** java_init_decl_processing (void)
*** 1189,1197 ****
  			    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
--- 1189,1200 ----
  			    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
Index: gcc/libfuncs.h
===================================================================
*** gcc/libfuncs.h.orig	2009-08-31 15:50:38.000000000 +0200
--- gcc/libfuncs.h	2009-09-08 15:27:39.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-08-31 15:50:38.000000000 +0200
--- gcc/optabs.c	2009-09-08 15:27:39.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-04 15:05:56.000000000 +0200
--- gcc/tree.h	2009-09-08 15:27:39.000000000 +0200
*************** struct GTY(()) tree_decl_minimal {
*** 2533,2538 ****
--- 2533,2541 ----
  #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 {
*** 3183,3188 ****
--- 3186,3194 ----
  
    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;
*** 4556,4561 ****
--- 4562,4570 ----
  
  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/objc/objc-act.c
===================================================================
*** gcc/objc/objc-act.c.orig	2009-09-08 15:27:29.000000000 +0200
--- gcc/objc/objc-act.c	2009-09-08 15:28:39.000000000 +0200
*************** objc_init_exceptions (void)
*** 3508,3518 ****
  #ifndef OBJCPLUS
    if (!flag_objc_sjlj_exceptions)
      {
!       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 ();
      }
--- 3508,3517 ----
  #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 ();
      }
Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c.orig	2009-09-04 21:19:48.000000000 +0200
--- gcc/toplev.c	2009-09-08 15:27:39.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/cp/except.c
===================================================================
*** gcc/cp/except.c.orig	2009-09-08 15:27:29.000000000 +0200
--- gcc/cp/except.c	2009-09-08 15:27:39.000000000 +0200
*************** init_exception_processing (void)
*** 77,85 ****
    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
--- 77,87 ----
    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
*************** decl_is_java_type (tree decl, int err)
*** 311,317 ****
  /* 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
*** 352,360 ****
      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/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c.orig	2009-09-04 15:05:56.000000000 +0200
--- gcc/dwarf2out.c	2009-09-08 15:27:39.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-04 15:05:56.000000000 +0200
--- gcc/expr.h	2009-09-08 15:27:39.000000000 +0200
*************** extern void init_all_optabs (void);
*** 814,819 ****
--- 814,845 ----
  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);
+ }
+ 
+ /* Extracts the personality function of DECL and returns the corresponding
+    libfunc. */
+ 
+ static inline rtx
+ get_personality_function (tree decl)
+ {
+   tree personality = DECL_FUNCTION_PERSONALITY (decl);
+   tree name;
+   if (!personality)
+     return NULL;
+ 
+   name = DECL_ASSEMBLER_NAME (personality);
+ 
+   return init_one_libfunc (IDENTIFIER_POINTER (name));
+ }
+ 
  extern int vector_mode_valid_p (enum machine_mode);
  
  #endif /* GCC_EXPR_H */
Index: gcc/ada/gcc-interface/misc.c
===================================================================
*** gcc/ada/gcc-interface/misc.c.orig	2009-09-08 15:27:29.000000000 +0200
--- gcc/ada/gcc-interface/misc.c	2009-09-08 15:27:39.000000000 +0200
*************** gnat_init_gcc_eh (void)
*** 431,439 ****
       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;
    default_init_unwind_resume_libfunc ();
  
--- 431,441 ----
       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 ();
  
Index: gcc/c-decl.c
===================================================================
*** gcc/c-decl.c.orig	2009-09-08 15:27:29.000000000 +0200
--- gcc/c-decl.c	2009-09-08 15:29:22.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 ();
  }
Index: gcc/fortran/f95-lang.c
===================================================================
*** gcc/fortran/f95-lang.c.orig	2009-09-08 15:27:21.000000000 +0200
--- gcc/fortran/f95-lang.c	2009-09-08 15:27:39.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/except.c
===================================================================
*** gcc/except.c.orig	2009-09-08 15:27:29.000000000 +0200
--- gcc/except.c	2009-09-08 15:27:39.000000000 +0200
*************** sjlj_emit_function_enter (rtx dispatch_l
*** 2421,2426 ****
--- 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
*** 2429,2437 ****
    /* 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,
*** 4391,4397 ****
  
  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
*** 4407,4413 ****
  #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
*** 4577,4592 ****
  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 ());
  }
Index: gcc/c-tree.h
===================================================================
*** gcc/c-tree.h.orig	2009-08-20 18:08:09.000000000 +0200
--- gcc/c-tree.h	2009-09-08 15:29:33.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-08 15:27:21.000000000 +0200
--- gcc/tree-eh.c	2009-09-08 15:30:35.000000000 +0200
*************** lower_eh_constructs (void)
*** 1939,1944 ****
--- 1939,1948 ----
    htab_delete (finally_tree);
  
    collect_eh_region_array ();
+ 
+   /* ??? If eh tree is non-empty.  */
+   DECL_FUNCTION_PERSONALITY (current_function_decl) = eh_personality_decl;
+ 
    return 0;
  }
  


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