From: Richard Guenther <rguenther@suse.de>
To: Richard Henderson <rth@redhat.com>
Cc: gcc-patches@gcc.gnu.org, Diego Novillo <dnovillo@google.com>
Subject: Re: [PATCH] Merge from LTO: eh_personality changes
Date: Fri, 11 Sep 2009 13:25:00 -0000 [thread overview]
Message-ID: <alpine.LNX.2.00.0909111521160.28140@zhemvz.fhfr.qr> (raw)
In-Reply-To: <4AA927E0.3080104@redhat.com>
On Thu, 10 Sep 2009, Richard Henderson wrote:
> On 09/10/2009 09:05 AM, Richard Guenther wrote:
> > No. It needs it for OMP and the MUST_NOT_THROW regions that generates.
>
> Ah, but we just need *some* personality, not any particular personality, since
> we don't have a language spec telling us that we have to call a particular
> abort function. Same goes for C.
>
> So you have C and Fortran leave its lang.eh_personality NULL, which leaves
> DECL_EH_PERSONALITY NULL, which allows your inliner change to drop in the C++
> (or Ada, etc) personality when needed.
>
> If we arrive at assembly output time in get_personality_function and find that
> the function has a non-NULL fun->eh->region_tree, then we supply the default
> __gcc_personality_v0. (Note the non-null region_tree here, since we need
> *some* personality even to handle cleanup regions at runtime. But *any*
> personality can handle cleanup regions, which is why we don't want to select a
> DECL_EH_PERSONALITY too early for that case.)
Ok, so the following implements that, creates a langhook to query the
units personality, properly uses DECL_RTL in get_personality_function
and moves the inlining fixups to the inliner, not changing the
personalities in the edge predicate. It also adds personality setting
to late functions coming via cgraph_add_new_function (which fixes a
bunch of OMP ICEs I get otherwise).
Boostrapped and tested a slightly older version ok, re-bootstrap and
test running on x86_64-unknown-linux-gnu.
The C++ FE handling of Java vs. C++ personality could need some cleanup
now that we can have per-function personalities.
Ok for trunk?
Thanks,
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_EH_PERSONALITY): Likewise.
(LANG_HOOKS_INITIALIZER): Adjust.
(lhd_pass_through_t): Declare.
* langhooks.h (struct lang_hooks): Add init_eh, eh_runtime_type and
eh_personality.
* 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 (get_personality_function): Declare.
* expr.c (get_personality_function): New function.
(build_personality_function): Likewise.
* 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.
* tree.h (DECL_FUNCTION_PERSONALITY): New.
(tree_function_decl): Add personality.
(lhd_gcc_personality): Declare.
(build_personality_function): Likewise.
* tree.c (gcc_eh_personality_decl): New.
(lhd_gcc_personality): New function.
* except.h (lang_eh_runtime_type): Remove.
(enum eh_personality_kind): New.
(build_personality_function): Declare.
(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.
(expand_call_inline): Likewise. Adjust the callers EH personality.
(tree_function_versioning): Copy DECL_FUNCTION_PERSONALITY.
* cgraph.c (cgraph_add_new_function): Set DECL_FUNCTION_PERSONALITY.
* Makefile.in (cgraph.o): Add $(EXCEPT_H) dependency.
* 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.
(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.
Do not set objc_init_exceptions. Move warning code ...
(objc_begin_try_stmt): ... here
(objc_build_throw_stmt): ... and here.
(objc_eh_personality_decl): New.
(objc_eh_personality): New function.
* objc-act.h (objc_init_exceptions): Declare.
(objc_eh_runtime_type): Likewise.
(objc_eh_personality): Likewise.
* objc-lang.c (LANG_HOOKS_INIT_EH): Define.
(LANG_HOOKS_EH_RUNTIME_TYPE): Likewise.
(LANG_HOOKS_EH_PERSONALITY): Likewise.
cp/
* except.c (init_exception_processing): Do not set
lang_eh_runtime_type.
(choose_personality_routine): Do not set eh_personality_decl,
set pragma_java_exceptions.
* cp-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
(LANG_HOOKS_EH_PERSONALITY): Likewise.
(cp_eh_personality_decl): New.
(cp_eh_personality): Likewise.
* Make-lang.in (cp-lang.o): Add $(EXPR_H) and $(EXCEPT_H)
dependencies.
java/
* decl.c (do_nothing): Remove.
(java_init_decl_processing): Do not set lang_eh_runtime_type.
* Make-lang.in (lang.o): Add $(EXCEPT_H) dependency.
* lang.c (java_eh_personality): New.
(java_eh_personality_decl): Likewise.
(LANG_HOOKS_EH_PERSONALITY): Define.
ada/
* gcc-interface/misc.c (gnat_init_gcc_eh): Do not set
lang_eh_runtime_type.
(LANG_HOOKS_EH_PERSONALITY): Define.
(gnat_eh_personality_decl): New.
(gnat_eh_personality): Likewise.
* Make-lang.in (misc.o): Add gt-ada-misc.h dependency.
* config-lang.in (gtfiles): Add misc.c.
fortran/
* f95-lang.c (gfc_maybe_initialize_eh): Do not init
eh_personality_libfunc.
Index: gcc/objc/objc-act.c
===================================================================
*** gcc/objc/objc-act.c.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/objc/objc-act.c 2009-09-11 13:58:30.000000000 +0200
*************** struct objc_try_context
*** 3483,3503 ****
static struct objc_try_context *cur_try_context;
/* This hook, called via lang_eh_runtime_type, generates a runtime object
that represents TYPE. For Objective-C, this is just the class name. */
/* ??? 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);
}
#endif
/* Initialize exception handling. */
! static void
objc_init_exceptions (void)
{
static bool done = false;
--- 3483,3518 ----
static struct objc_try_context *cur_try_context;
+ static GTY(()) tree objc_eh_personality_decl;
+
/* This hook, called via lang_eh_runtime_type, generates a runtime object
that represents TYPE. For Objective-C, this is just the class name. */
/* ??? 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);
}
+
+ tree
+ objc_eh_personality (void)
+ {
+ if (!flag_objc_sjlj_exceptions
+ && !objc_eh_personality_decl)
+ objc_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gnu_objc_personality_sj0"
+ : "__gnu_objc_personality_v0");
+
+ return objc_eh_personality_decl;
+ }
#endif
/* 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
}
--- 3520,3530 ----
return;
done = true;
#ifndef OBJCPLUS
! if (!flag_objc_sjlj_exceptions)
{
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);
--- 3825,3838 ----
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)
{
--- 3981,3994 ----
{
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-11 13:56:48.000000000 +0200
--- gcc/c-decl.c 2009-09-11 13:58:30.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,4057 ----
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;
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);
}
}
--- 4356,4361 ----
Index: gcc/c-parser.c
===================================================================
*** gcc/c-parser.c.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/c-parser.c 2009-09-11 13:58:30.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-11 13:56:48.000000000 +0200
--- gcc/c-lang.c 2009-09-11 13:58:30.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-11 13:56:48.000000000 +0200
--- gcc/langhooks-def.h 2009-09-11 13:58:30.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,116 ----
#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_PERSONALITY lhd_gcc_personality
+ #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 ****
--- 275,283 ----
LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \
LANG_HOOKS_INIT_TS, \
LANG_HOOKS_EXPR_TO_DECL, \
+ LANG_HOOKS_INIT_EH, \
+ LANG_HOOKS_EH_PERSONALITY, \
+ LANG_HOOKS_EH_RUNTIME_TYPE, \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
Index: gcc/langhooks.h
===================================================================
*** gcc/langhooks.h.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/langhooks.h 2009-09-11 13:58:30.000000000 +0200
*************** struct lang_hooks
*** 414,419 ****
--- 414,428 ----
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);
+
+ /* The EH personality function decl. */
+ tree (*eh_personality) (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-11 13:56:48.000000000 +0200
--- gcc/objc/objc-act.h 2009-09-11 13:58:30.000000000 +0200
*************** const char *objc_printable_name (tree, i
*** 32,37 ****
--- 32,40 ----
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);
+ tree objc_eh_personality (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-11 13:56:48.000000000 +0200
--- gcc/objc/objc-lang.c 2009-09-11 13:58:30.000000000 +0200
*************** static void objc_init_ts (void);
*** 50,55 ****
--- 50,64 ----
#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_PERSONALITY
+ #define LANG_HOOKS_EH_PERSONALITY objc_eh_personality
+ #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-11 13:56:48.000000000 +0200
--- gcc/ada/gcc-interface/misc.c 2009-09-11 13:58:30.000000000 +0200
*************** static void gnat_parse_file (int);
*** 79,84 ****
--- 79,85 ----
static void internal_error_function (const char *, va_list *);
static tree gnat_type_max_size (const_tree);
static void gnat_get_subrange_bounds (const_tree, tree *, tree *);
+ static tree gnat_eh_personality (void);
/* Definitions for our language-specific hooks. */
*************** static void gnat_get_subrange_bounds (co
*** 129,135 ****
#undef LANG_HOOKS_ATTRIBUTE_TABLE
#define LANG_HOOKS_ATTRIBUTE_TABLE gnat_internal_attribute_table
#undef LANG_HOOKS_BUILTIN_FUNCTION
! #define LANG_HOOKS_BUILTIN_FUNCTION gnat_builtin_function
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
--- 130,138 ----
#undef LANG_HOOKS_ATTRIBUTE_TABLE
#define LANG_HOOKS_ATTRIBUTE_TABLE gnat_internal_attribute_table
#undef LANG_HOOKS_BUILTIN_FUNCTION
! #define LANG_HOOKS_BUILTIN_FUNCTION gnat_builtin_function
! #undef LANG_HOOKS_EH_PERSONALITY
! #define LANG_HOOKS_EH_PERSONALITY gnat_eh_personality
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
*************** 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
--- 434,440 ----
*************** fp_size_to_prec (int size)
*** 811,813 ****
--- 810,828 ----
gcc_unreachable ();
}
+
+ static GTY(()) tree gnat_eh_personality_decl;
+
+ static tree
+ gnat_eh_personality (void)
+ {
+ if (!gnat_eh_personality_decl)
+ gnat_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gnat_eh_personality_sj"
+ : "__gnat_eh_personality");
+
+ return gnat_eh_personality_decl;
+ }
+
+ #include "gt-ada-misc.h"
Index: gcc/cp/cp-lang.c
===================================================================
*** gcc/cp/cp-lang.c.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/cp/cp-lang.c 2009-09-11 13:58:30.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 32,42 ****
--- 32,45 ----
#include "debug.h"
#include "cp-objcp-common.h"
#include "hashtab.h"
+ #include "except.h"
+ #include "expr.h"
enum c_language_kind c_language = clk_cxx;
static void cp_init_ts (void);
static const char * cxx_dwarf_name (tree t, int verbosity);
static enum classify_record cp_classify_record (tree type);
+ static tree cp_eh_personality (void);
/* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h;
consequently, there should be very few hooks below. */
*************** static enum classify_record cp_classify_
*** 71,76 ****
--- 74,83 ----
#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_PERSONALITY
+ #define LANG_HOOKS_EH_PERSONALITY cp_eh_personality
+ #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;
*************** finish_file (void)
*** 145,148 ****
--- 152,177 ----
{
}
+ static GTY(()) tree cp_eh_personality_decl;
+
+ static tree
+ cp_eh_personality (void)
+ {
+ if (!cp_eh_personality_decl)
+ {
+ if (!pragma_java_exceptions)
+ cp_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gxx_personality_sj0"
+ : "__gxx_personality_v0");
+ else
+ cp_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gcj_personality_sj0"
+ : "__gcj_personality_v0");
+ }
+
+ return cp_eh_personality_decl;
+ }
+
#include "gtype-cp.h"
Index: gcc/cp/except.c
===================================================================
*** gcc/cp/except.c.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/cp/except.c 2009-09-11 13:58:30.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,87 ----
*************** 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);
--- 138,144 ----
/* 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
--- 308,314 ----
/* 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:
--- 349,355 ----
case lang_java:
state = chose_java;
terminate_node = built_in_decls [BUILT_IN_ABORT];
! pragma_java_exceptions = true;
break;
default:
Index: gcc/except.c
===================================================================
*** gcc/except.c.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/except.c 2009-09-11 13:58:30.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,4675 ----
return fun->eh->throw_stmt_table;
}
+ /* Return true if the function deeds a EH personality function. */
+
+ enum eh_personality_kind
+ function_needs_eh_personality (struct function *fn)
+ {
+ struct eh_region_d *i;
+ int depth = 0;
+ enum eh_personality_kind kind = eh_personality_none;
+
+ i = fn->eh->region_tree;
+ if (!i)
+ return eh_personality_none;
+
+ while (1)
+ {
+ switch (i->type)
+ {
+ case ERT_TRY:
+ case ERT_THROW:
+ /* Do not need a EH personality function. */
+ break;
+
+ case ERT_MUST_NOT_THROW:
+ /* Always needs a EH personality function. */
+ return eh_personality_lang;
+
+ case ERT_CLEANUP:
+ /* Can do with any personality including the generic C one. */
+ kind = eh_personality_any;
+ break;
+
+ case ERT_CATCH:
+ case ERT_ALLOWED_EXCEPTIONS:
+ /* Always needs a EH personality function. The generic C
+ personality doesn't handle these even for empty type lists. */
+ return eh_personality_lang;
+
+ case ERT_UNKNOWN:
+ return eh_personality_lang;
+ }
+ /* 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 kind;
+ }
+ while (i->next_peer == NULL);
+ i = i->next_peer;
+ }
+ }
+
+ return kind;
+ }
+
/* Dump EH information to OUT. */
void
Index: gcc/except.h
===================================================================
*** gcc/except.h.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/except.h 2009-09-11 13:58:30.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,285 ----
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);
+
+ enum eh_personality_kind {
+ eh_personality_none,
+ eh_personality_any,
+ eh_personality_lang
+ };
+
+ extern enum eh_personality_kind
+ function_needs_eh_personality (struct function *);
Index: gcc/java/decl.c
===================================================================
*** gcc/java/decl.c.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/java/decl.c 2009-09-11 13:58:30.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,1200 ----
0, NOT_BUILT_IN, NULL, NULL_TREE);
/* Initialize variables for except.c. */
!
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-11 13:56:48.000000000 +0200
--- gcc/langhooks.c 2009-09-11 13:58:30.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-11 13:56:48.000000000 +0200
--- gcc/cp/cp-tree.h 2009-09-11 13:58:30.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-11 13:56:48.000000000 +0200
--- gcc/libfuncs.h 2009-09-11 13:58:30.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-11 13:56:48.000000000 +0200
--- gcc/optabs.c 2009-09-11 13:58:30.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-11 13:57:36.000000000 +0200
--- gcc/tree.h 2009-09-11 13:58:30.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 {
*** 3190,3195 ****
--- 3193,3201 ----
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 bool auto_var_in_fn_p (const_tree
*** 4652,4657 ****
--- 4658,4664 ----
extern tree build_low_bits_mask (tree, unsigned);
extern tree tree_strip_nop_conversions (tree);
extern tree tree_strip_sign_nop_conversions (tree);
+ extern tree lhd_gcc_personality (void);
\f
/* In cgraph.c */
extern void change_decl_assembler_name (tree, tree);
*************** extern unsigned HOST_WIDE_INT compute_bu
*** 5263,5268 ****
--- 5270,5276 ----
/* In expr.c. */
extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
+ extern tree build_personality_function (const char *);
/* In tree-inline.c. */
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/dwarf2out.c 2009-09-11 13:58:30.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-11 13:56:48.000000000 +0200
--- gcc/expr.h 2009-09-11 13:58:30.000000000 +0200
*************** extern void init_all_optabs (void);
*** 814,819 ****
--- 814,825 ----
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 *);
+
+ /* 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-11 13:56:48.000000000 +0200
--- gcc/fortran/f95-lang.c 2009-09-11 13:58:30.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,1160 ----
Index: gcc/c-tree.h
===================================================================
*** gcc/c-tree.h.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/c-tree.h 2009-09-11 13:58:30.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-11 13:56:48.000000000 +0200
--- gcc/tree-eh.c 2009-09-11 13:58:30.000000000 +0200
*************** lower_eh_constructs (void)
*** 1939,1944 ****
--- 1939,1952 ----
htab_delete (finally_tree);
collect_eh_region_array ();
+
+ /* If this function needs a language specific EH personality routine
+ and the frontend didn't already set one do so now. */
+ if (function_needs_eh_personality (cfun) == eh_personality_lang
+ && !DECL_FUNCTION_PERSONALITY (current_function_decl))
+ DECL_FUNCTION_PERSONALITY (current_function_decl)
+ = lang_hooks.eh_personality ();
+
return 0;
}
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c.orig 2009-09-11 13:57:36.000000000 +0200
--- gcc/tree-inline.c 2009-09-11 13:58:30.000000000 +0200
*************** expand_call_inline (basic_block bb, gimp
*** 3505,3510 ****
--- 3505,3517 ----
cg_edge = cgraph_edge (id->dst_node, stmt);
+ /* Don't inline functions with different EH personalities. */
+ if (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
+ && DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)
+ && (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
+ != DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)))
+ goto egress;
+
/* Don't try to inline functions that are not well-suited to
inlining. */
if (!cgraph_inline_p (cg_edge, &reason))
*************** expand_call_inline (basic_block bb, gimp
*** 3546,3551 ****
--- 3553,3563 ----
/* We will be inlining this callee. */
id->eh_region = lookup_stmt_eh_region (stmt);
+ /* Update the callers EH personality. */
+ if (DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl))
+ DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl)
+ = DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl);
+
/* Split the block holding the GIMPLE_CALL. */
e = split_block (bb, stmt);
bb = e->src;
*************** tree_function_versioning (tree old_decl,
*** 4730,4735 ****
--- 4742,4748 ----
DECL_ARTIFICIAL (new_decl) = 1;
DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl);
+ DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl);
/* Prepare the data structures for the tree copy. */
memset (&id, 0, sizeof (id));
*************** tree_can_inline_p (struct cgraph_edge *e
*** 5000,5005 ****
--- 5013,5030 ----
caller = e->caller->decl;
callee = e->callee->decl;
+ /* We cannot inline a function that uses a different EH personality
+ than the caller. */
+ if (DECL_FUNCTION_PERSONALITY (caller)
+ && 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-11 13:57:36.000000000 +0200
--- gcc/expr.c 2009-09-11 13:58:30.000000000 +0200
*************** const_vector_from_tree (tree exp)
*** 10214,10217 ****
--- 10214,10265 ----
return gen_rtx_CONST_VECTOR (mode, v);
}
+
+
+ /* Build a decl for a EH personality function named NAME. */
+
+ tree
+ build_personality_function (const char *name)
+ {
+ tree decl, type;
+
+ type = build_function_type_list (integer_type_node, integer_type_node,
+ long_long_unsigned_type_node,
+ ptr_type_node, ptr_type_node, NULL_TREE);
+ decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
+ get_identifier (name), type);
+ 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);
+
+ return decl;
+ }
+
+ /* Extracts the personality function of DECL and returns the corresponding
+ libfunc. */
+
+ rtx
+ get_personality_function (tree decl)
+ {
+ tree personality = DECL_FUNCTION_PERSONALITY (decl);
+ enum eh_personality_kind pk;
+
+ pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl));
+ if (pk == eh_personality_none)
+ return NULL;
+
+ if (!personality
+ && pk == eh_personality_any)
+ personality = lang_hooks.eh_personality ();
+
+ if (pk == eh_personality_lang)
+ gcc_assert (personality != NULL_TREE);
+
+ return XEXP (DECL_RTL (personality), 0);
+ }
+
#include "gt-expr.h"
Index: gcc/ada/gcc-interface/Make-lang.in
===================================================================
*** gcc/ada/gcc-interface/Make-lang.in.orig 2009-09-11 13:57:35.000000000 +0200
--- gcc/ada/gcc-interface/Make-lang.in 2009-09-11 13:58:30.000000000 +0200
*************** ada/misc.o : ada/gcc-interface/misc.c $(
*** 1072,1078 ****
$(LANGHOOKS_DEF_H) opts.h options.h $(TREE_INLINE_H) \
ada/gcc-interface/ada.h ada/adadecode.h ada/types.h ada/atree.h \
ada/elists.h ada/namet.h ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h \
! ada/sinfo.h ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h
$(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/targtyps.o : ada/gcc-interface/targtyps.c $(CONFIG_H) $(SYSTEM_H) \
--- 1072,1079 ----
$(LANGHOOKS_DEF_H) opts.h options.h $(TREE_INLINE_H) \
ada/gcc-interface/ada.h ada/adadecode.h ada/types.h ada/atree.h \
ada/elists.h ada/namet.h ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h \
! ada/sinfo.h ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h \
! gt-ada-misc.h
$(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@
ada/targtyps.o : ada/gcc-interface/targtyps.c $(CONFIG_H) $(SYSTEM_H) \
Index: gcc/ada/gcc-interface/config-lang.in
===================================================================
*** gcc/ada/gcc-interface/config-lang.in.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/ada/gcc-interface/config-lang.in 2009-09-11 13:58:30.000000000 +0200
*************** boot_language_boot_flags='ADAFLAGS="$(BO
*** 32,38 ****
compilers="gnat1\$(exeext)"
! gtfiles="\$(srcdir)/ada/gcc-interface/ada-tree.h \$(srcdir)/ada/gcc-interface/gigi.h \$(srcdir)/ada/gcc-interface/decl.c \$(srcdir)/ada/gcc-interface/trans.c \$(srcdir)/ada/gcc-interface/utils.c"
outputs="ada/gcc-interface/Makefile ada/Makefile"
--- 32,38 ----
compilers="gnat1\$(exeext)"
! gtfiles="\$(srcdir)/ada/gcc-interface/ada-tree.h \$(srcdir)/ada/gcc-interface/gigi.h \$(srcdir)/ada/gcc-interface/decl.c \$(srcdir)/ada/gcc-interface/trans.c \$(srcdir)/ada/gcc-interface/utils.c \$(srcdir)/ada/gcc-interface/misc.c"
outputs="ada/gcc-interface/Makefile ada/Makefile"
Index: gcc/cp/Make-lang.in
===================================================================
*** gcc/cp/Make-lang.in.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/cp/Make-lang.in 2009-09-11 13:58:30.000000000 +0200
*************** cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H)
*** 250,256 ****
$(C_PRAGMA_H) toplev.h output.h input.h cp/operators.def $(TM_P_H)
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h \
$(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-cp.h \
! $(DIAGNOSTIC_H) cp/cp-objcp-common.h
cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \
output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
cp/operators.def $(TM_P_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(C_PRAGMA_H) \
--- 250,256 ----
$(C_PRAGMA_H) toplev.h output.h input.h cp/operators.def $(TM_P_H)
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h \
$(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-cp.h \
! $(DIAGNOSTIC_H) cp/cp-objcp-common.h $(EXPR_H) $(EXCEPT_H)
cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \
output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
cp/operators.def $(TM_P_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(C_PRAGMA_H) \
Index: gcc/java/Make-lang.in
===================================================================
*** gcc/java/Make-lang.in.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/java/Make-lang.in 2009-09-11 13:58:30.000000000 +0200
*************** java/jvgenmain.o: java/jvgenmain.c $(CON
*** 284,290 ****
coretypes.h $(TM_H) intl.h
java/lang.o: java/lang.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h input.h \
toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(EXPR_H) $(DIAGNOSTIC_H) \
! langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h
java/mangle.o: java/mangle.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) $(SYSTEM_H) \
coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h $(LANGHOOKS_DEF_H)
java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \
--- 284,290 ----
coretypes.h $(TM_H) intl.h
java/lang.o: java/lang.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h input.h \
toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(EXPR_H) $(DIAGNOSTIC_H) \
! langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h $(EXCEPT_H)
java/mangle.o: java/mangle.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) $(SYSTEM_H) \
coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h $(LANGHOOKS_DEF_H)
java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \
Index: gcc/java/lang.c
===================================================================
*** gcc/java/lang.c.orig 2009-09-11 13:56:48.000000000 +0200
--- gcc/java/lang.c 2009-09-11 13:58:30.000000000 +0200
*************** The Free Software Foundation is independ
*** 45,50 ****
--- 45,51 ----
#include "tree-dump.h"
#include "opts.h"
#include "options.h"
+ #include "except.h"
static bool java_init (void);
static void java_finish (void);
*************** static bool java_decl_ok_for_sibcall (co
*** 64,69 ****
--- 65,72 ----
static enum classify_record java_classify_record (tree type);
+ static tree java_eh_personality (void);
+
#ifndef TARGET_OBJECT_SUFFIX
# define TARGET_OBJECT_SUFFIX ".o"
#endif
*************** struct GTY(()) language_function {
*** 158,163 ****
--- 161,169 ----
#undef LANG_HOOKS_ATTRIBUTE_TABLE
#define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table
+ #undef LANG_HOOKS_EH_PERSONALITY
+ #define LANG_HOOKS_EH_PERSONALITY java_eh_personality
+
/* Each front end provides its own. */
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
*************** java_classify_record (tree type)
*** 880,883 ****
--- 886,903 ----
return RECORD_IS_CLASS;
}
+ static GTY(()) tree java_eh_personality_decl;
+
+ static tree
+ java_eh_personality (void)
+ {
+ if (!java_eh_personality_decl)
+ java_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gcj_personality_sj0"
+ : "__gcj_personality_v0");
+
+ return java_eh_personality_decl;
+ }
+
#include "gt-java-lang.h"
Index: gcc/tree.c
===================================================================
*** gcc/tree.c.orig 2009-09-11 13:57:36.000000000 +0200
--- gcc/tree.c 2009-09-11 13:58:30.000000000 +0200
*************** tree_strip_sign_nop_conversions (tree ex
*** 10566,10570 ****
--- 10566,10585 ----
return exp;
}
+ static GTY(()) tree gcc_eh_personality_decl;
+
+ /* Return the GCC personality function decl. */
+
+ tree
+ lhd_gcc_personality (void)
+ {
+ if (!gcc_eh_personality_decl)
+ gcc_eh_personality_decl
+ = build_personality_function (USING_SJLJ_EXCEPTIONS
+ ? "__gcc_personality_sj0"
+ : "__gcc_personality_v0");
+
+ return gcc_eh_personality_decl;
+ }
#include "gt-tree.h"
Index: gcc/Makefile.in
===================================================================
*** gcc/Makefile.in.orig 2009-09-09 11:28:58.000000000 +0200
--- gcc/Makefile.in 2009-09-11 15:12:28.000000000 +0200
*************** simplify-rtx.o : simplify-rtx.c $(CONFIG
*** 2767,2773 ****
cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
! $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
--- 2767,2773 ----
cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \
gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
! $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h $(EXCEPT_H)
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
Index: gcc/cgraph.c
===================================================================
*** gcc/cgraph.c.orig 2009-09-04 15:05:56.000000000 +0200
--- gcc/cgraph.c 2009-09-11 15:10:55.000000000 +0200
*************** The callgraph:
*** 84,89 ****
--- 84,90 ----
#include "tree-dump.h"
#include "tree-flow.h"
#include "value-prof.h"
+ #include "except.h"
static void cgraph_node_remove_callers (struct cgraph_node *node);
static inline void cgraph_edge_remove_caller (struct cgraph_edge *e);
*************** cgraph_add_new_function (tree fndecl, bo
*** 1953,1958 ****
--- 1954,1965 ----
current_function_decl = NULL;
break;
}
+
+ /* Set a personality if required and we already passed EH lowering. */
+ if (lowered
+ && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl))
+ == eh_personality_lang))
+ DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
}
/* Return true if NODE can be made local for API change.
next prev parent reply other threads:[~2009-09-11 13:25 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-04 13:34 Richard Guenther
2009-09-04 13:37 ` Diego Novillo
2009-09-04 13:41 ` Richard Guenther
2009-09-05 16:37 ` Richard Henderson
2009-09-05 16:38 ` Richard Henderson
2009-09-05 17:24 ` Richard Guenther
2009-09-05 18:11 ` Richard Henderson
2009-09-08 12:37 ` Richard Guenther
2009-09-08 15:20 ` Richard Guenther
2009-09-08 15:49 ` Richard Henderson
2009-09-10 13:12 ` Richard Guenther
2009-09-10 14:37 ` Richard Guenther
2009-09-10 14:52 ` Richard Guenther
2009-09-10 15:50 ` Richard Henderson
2009-09-10 16:02 ` Richard Guenther
2009-09-10 16:06 ` Richard Guenther
2009-09-10 16:23 ` Richard Henderson
2009-09-11 13:25 ` Richard Guenther [this message]
2009-09-11 15:41 ` Richard Henderson
2009-09-11 16:41 ` Richard Guenther
2009-09-11 17:05 ` Richard Henderson
2009-09-13 22:57 ` H.J. Lu
2010-12-29 5:30 ` H.J. Lu
2010-12-29 5:36 ` H.J. Lu
2011-02-08 2:06 ` H.J. Lu
2009-09-10 16:12 ` Richard Henderson
2009-09-10 15:50 ` Richard Guenther
2009-09-10 15:57 ` Richard Henderson
2009-09-08 17:38 ` Eric Botcazou
2009-09-08 15:48 ` Richard Henderson
2009-09-08 16:04 ` Richard Guenther
2009-09-09 9:34 ` Richard Guenther
2009-09-09 15:24 ` Richard Henderson
2009-09-09 15:26 ` Richard Guenther
2009-09-14 2:43 David Edelsohn
2009-09-14 5:38 ` Gerald Pfeifer
2009-09-14 9:37 ` Richard Guenther
2009-09-15 8:15 ` Gerald Pfeifer
2009-09-15 11:48 ` David Edelsohn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LNX.2.00.0909111521160.28140@zhemvz.fhfr.qr \
--to=rguenther@suse.de \
--cc=dnovillo@google.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=rth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).