This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Merge from LTO: eh_personality changes
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Diego Novillo <dnovillo at google dot com>
- Date: Fri, 4 Sep 2009 15:34:27 +0200 (CEST)
- Subject: [PATCH] Merge from LTO: eh_personality changes
This merges the eh_personality changes from the branch. It moves us
to store the eh personality decl per function. The entanglement
between the C and ObjC frontends makes a new langhook necessary to
initialize the personality decl - other frontends don't really need it.
Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?
This is the last non-LTO specific bits after fld merge on the branch.
Thanks,
Richard.
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.
* lto-function-in.c (lto_init_eh): Don't set eh_personality_libfunc.
(input_function_decl): Read decl->function_decl.personality.
* lto-function-out.c (output_function_decl): Write
decl->function_decl.personality.
* 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-03 16:53:25.000000000 +0200
--- gcc/java/decl.c 2009-09-03 17:04:07.000000000 +0200
*************** java_init_decl_processing (void)
*** 1195,1203 ****
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
--- 1195,1206 ----
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-09-03 16:53:25.000000000 +0200
--- gcc/libfuncs.h 2009-09-03 17:04:07.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-03 16:53:25.000000000 +0200
--- gcc/optabs.c 2009-09-03 17:04:07.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-03 16:53:26.000000000 +0200
--- gcc/tree.h 2009-09-03 17:04:07.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-03 16:53:26.000000000 +0200
--- gcc/objc/objc-act.c 2009-09-03 18:57:23.000000000 +0200
*************** 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,3526 ****
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;
--- 3505,3519 ----
return;
done = true;
#ifndef OBJCPLUS
! if (!flag_objc_sjlj_exceptions)
{
c_eh_initialized_p = true;
! 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 ();
lang_eh_runtime_type = objc_eh_runtime_type;
*************** 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);
--- 3817,3830 ----
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)
{
--- 3973,3986 ----
{
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/toplev.c
===================================================================
*** gcc/toplev.c.orig 2009-09-03 16:53:26.000000000 +0200
--- gcc/toplev.c 2009-09-03 17:04:07.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-03 16:53:26.000000000 +0200
--- gcc/cp/except.c 2009-09-03 17:04:07.000000000 +0200
*************** init_exception_processing (void)
*** 78,86 ****
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
--- 78,88 ----
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)
*** 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
--- 315,321 ----
/* 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:
--- 356,365 ----
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-03 16:53:26.000000000 +0200
--- gcc/dwarf2out.c 2009-09-03 17:04:07.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-03 16:53:26.000000000 +0200
--- gcc/expr.h 2009-09-03 17:04:07.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-03 16:53:26.000000000 +0200
--- gcc/ada/gcc-interface/misc.c 2009-09-03 17:04:07.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;
lang_eh_runtime_type = gnat_return_tree;
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;
lang_eh_runtime_type = gnat_return_tree;
default_init_unwind_resume_libfunc ();
Index: gcc/c-decl.c
===================================================================
*** gcc/c-decl.c.orig 2009-09-03 16:53:26.000000000 +0200
--- gcc/c-decl.c 2009-09-03 17:04:07.000000000 +0200
*************** 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);
--- 2365,2372 ----
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);
*************** c_maybe_initialize_eh (void)
*** 4052,4061 ****
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 ();
}
--- 4053,4063 ----
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);
}
}
--- 4362,4367 ----
Index: gcc/fortran/f95-lang.c
===================================================================
*** gcc/fortran/f95-lang.c.orig 2009-09-03 16:53:26.000000000 +0200
--- gcc/fortran/f95-lang.c 2009-09-03 17:04:07.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-03 16:53:26.000000000 +0200
--- gcc/except.c 2009-09-03 17:04:07.000000000 +0200
*************** sjlj_emit_function_enter (rtx dispatch_l
*** 2424,2429 ****
--- 2424,2430 ----
{
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)
--- 2433,2441 ----
/* 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
--- 4395,4401 ----
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. */
--- 4411,4417 ----
#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 ());
}
--- 4581,4598 ----
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-parser.c
===================================================================
*** gcc/c-parser.c.orig 2009-09-03 16:53:26.000000000 +0200
--- gcc/c-parser.c 2009-09-03 17:25:23.000000000 +0200
*************** c_parse_file (void)
*** 8607,8612 ****
--- 8607,8615 ----
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/tree.c
===================================================================
*** gcc/tree.c.orig 2009-09-03 16:53:26.000000000 +0200
--- gcc/tree.c 2009-09-03 17:04:07.000000000 +0200
*************** make_node_stat (enum tree_code code MEM_
*** 867,872 ****
--- 867,873 ----
{
DECL_ALIGN (t) = FUNCTION_BOUNDARY;
DECL_MODE (t) = FUNCTION_MODE;
+ DECL_FUNCTION_PERSONALITY (t) = eh_personality_decl;
}
else
DECL_ALIGN (t) = 1;
Index: gcc/c-lang.c
===================================================================
*** gcc/c-lang.c.orig 2009-09-03 17:25:31.000000000 +0200
--- gcc/c-lang.c 2009-09-03 17:26:29.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-03 17:20:17.000000000 +0200
--- gcc/langhooks-def.h 2009-09-03 17:29:30.000000000 +0200
*************** extern void lhd_omp_firstprivatize_type_
*** 107,112 ****
--- 107,113 ----
#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
/* Attribute hooks. */
#define LANG_HOOKS_ATTRIBUTE_TABLE NULL
*************** extern tree lhd_make_node (enum tree_cod
*** 271,276 ****
--- 272,278 ----
LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \
LANG_HOOKS_INIT_TS, \
LANG_HOOKS_EXPR_TO_DECL, \
+ LANG_HOOKS_INIT_EH, \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
Index: gcc/langhooks.h
===================================================================
*** gcc/langhooks.h.orig 2009-09-03 17:20:17.000000000 +0200
--- gcc/langhooks.h 2009-09-03 17:22:05.000000000 +0200
*************** struct lang_hooks
*** 414,419 ****
--- 414,422 ----
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);
+
/* 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-03 17:24:39.000000000 +0200
--- gcc/objc/objc-act.h 2009-09-03 17:28:37.000000000 +0200
*************** const char *objc_printable_name (tree, i
*** 32,37 ****
--- 32,38 ----
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);
/* 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-03 17:23:12.000000000 +0200
--- gcc/objc/objc-lang.c 2009-09-03 17:24:19.000000000 +0200
*************** static void objc_init_ts (void);
*** 50,55 ****
--- 50,57 ----
#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
/* Each front end provides its own lang hook initializer. */
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;