OSDN Git Service

2009-09-13 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 13 Sep 2009 19:40:33 +0000 (19:40 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 13 Sep 2009 19:40:33 +0000 (19:40 +0000)
Rafael Avila de Espindola  <espindola@google.com>

* langhooks-def.h (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
(LANG_HOOKS_EH_PERSONALITY): Likewise.
(LANG_HOOKS_INITIALIZER): Adjust.
(lhd_pass_through_t): Declare.
* langhooks.h (struct lang_hooks): Add 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-parser.o): Likewise

* c-tree.h (c_eh_initialized_p): Remove.
(c_maybe_initialize_eh): Likewise.
* 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): Remove.
(c_maybe_initialize_eh): Likewise.
        * c-parser.c (c_parser_omp_construct): Likewise.
(c_parse_file): Initialize exception handling.

objc/
* objc-act.c (objc_eh_runtime_type): Export.
(objc_init_exceptions): Remove.  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_eh_runtime_type): Declare.
(objc_eh_personality): Likewise.
* objc-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@151676 138bc75d-0d04-0410-961f-82ee72b054a4

39 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/ada/ChangeLog
gcc/ada/gcc-interface/Make-lang.in
gcc/ada/gcc-interface/config-lang.in
gcc/ada/gcc-interface/misc.c
gcc/c-decl.c
gcc/c-parser.c
gcc/c-tree.h
gcc/cgraph.c
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/cp-lang.c
gcc/cp/cp-tree.h
gcc/cp/except.c
gcc/dwarf2out.c
gcc/except.c
gcc/except.h
gcc/expr.c
gcc/expr.h
gcc/fortran/ChangeLog
gcc/fortran/f95-lang.c
gcc/java/ChangeLog
gcc/java/Make-lang.in
gcc/java/decl.c
gcc/java/lang.c
gcc/langhooks-def.h
gcc/langhooks.c
gcc/langhooks.h
gcc/libfuncs.h
gcc/objc/ChangeLog
gcc/objc/objc-act.c
gcc/objc/objc-act.h
gcc/objc/objc-lang.c
gcc/optabs.c
gcc/tree-eh.c
gcc/tree-inline.c
gcc/tree.c
gcc/tree.h

index 06b5c43..21bf315 100644 (file)
@@ -1,3 +1,54 @@
+2009-09-13  Richard Guenther  <rguenther@suse.de>
+       Rafael Avila de Espindola  <espindola@google.com>
+
+       * langhooks-def.h (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
+       (LANG_HOOKS_EH_PERSONALITY): Likewise.
+       (LANG_HOOKS_INITIALIZER): Adjust.
+       (lhd_pass_through_t): Declare.
+       * langhooks.h (struct lang_hooks): Add 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-parser.o): Likewise
+       * c-tree.h (c_eh_initialized_p): Remove.
+       (c_maybe_initialize_eh): Likewise.
+       * 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): Remove.
+       (c_maybe_initialize_eh): Likewise.
+        * c-parser.c (c_parser_omp_construct): Likewise.
+       (c_parse_file): Initialize exception handling.
+
 2009-09-13  Kai Tietz  <kai.tietz@onevision.com>
 
        * config.gcc (tm_file): Remove i386/biarch32.h
index bd1c7f0..d89fb2a 100644 (file)
@@ -1909,7 +1909,7 @@ c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
 c-parser.o : c-parser.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
     $(GGC_H) $(TIMEVAR_H) $(C_TREE_H) $(INPUT_H) $(FLAGS_H) $(TOPLEV_H) output.h \
     $(CPPLIB_H) gt-c-parser.h $(RTL_H) langhooks.h $(C_COMMON_H) $(C_PRAGMA_H) \
-    vec.h $(TARGET_H) $(CGRAPH_H) $(PLUGIN_H)
+    vec.h $(TARGET_H) $(CGRAPH_H) $(PLUGIN_H) $(EXCEPT_H)
 
 srcextra: gcc.srcextra lang.srcextra
 
@@ -2767,7 +2767,7 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
 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
+   $(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 9ef2feb..7d4d8aa 100644 (file)
@@ -1,3 +1,14 @@
+2009-09-13  Richard Guenther  <rguenther@suse.de>
+       Rafael Avila de Espindola  <espindola@google.com>
+
+       * 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.
+
 2009-09-10  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        PR ada/18302
index d0eb5e8..163274c 100644 (file)
@@ -1072,7 +1072,8 @@ ada/misc.o : ada/gcc-interface/misc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(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
+   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 5825398..b4a28be 100644 (file)
@@ -32,7 +32,7 @@ boot_language_boot_flags='ADAFLAGS="$(BOOT_ADAFLAGS)"'
 
 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"
+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 f39a60e..261351f 100644 (file)
@@ -79,6 +79,7 @@ static void gnat_parse_file           (int);
 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.  */
 
@@ -129,7 +130,9 @@ static void gnat_get_subrange_bounds        (const_tree, tree *, tree *);
 #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
+#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;
 
@@ -431,11 +434,7 @@ gnat_init_gcc_eh (void)
      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
@@ -811,3 +810,19 @@ fp_size_to_prec (int size)
 
   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 1bc9791..ed8863d 100644 (file)
@@ -92,9 +92,6 @@ tree pending_invalid_xref;
 /* 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.  */
@@ -2365,7 +2362,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
     TREE_USED (olddecl) = 1;
 
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
-     But preserve OLDDECL's DECL_UID and DECL_CONTEXT.  */
+     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);
@@ -4043,23 +4041,6 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs,
   return tem;
 }
 
-/* Initialize EH if not initialized yet and exceptions are enabled.  */
-
-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 ();
-}
-
 /* Finish processing of a declaration;
    install its initial value.
    If ORIGTYPE is not NULL_TREE, it is the original type of INIT.
@@ -4360,9 +4341,6 @@ finish_decl (tree decl, location_t init_loc, tree init,
          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);
        }
     }
index 43b0c8c..ddb81e1 100644 (file)
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "cgraph.h"
 #include "plugin.h"
+#include "except.h"
 
 \f
 /* Initialization routine for this file.  */
@@ -8489,12 +8490,6 @@ c_parser_omp_construct (c_parser *parser)
   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:
@@ -8607,6 +8602,13 @@ c_parse_file (void)
   the_parser = GGC_NEW (c_parser);
   *the_parser = tparser;
 
+  /* Initialize EH, if we've been told to do so.  */
+  if (flag_exceptions)
+    {
+      default_init_unwind_resume_libfunc ();
+      using_eh_for_cleanups ();
+    }
+
   c_parser_translation_unit (the_parser);
   the_parser = NULL;
 }
index 502e6ef..5c1ccb5 100644 (file)
@@ -427,7 +427,6 @@ extern struct c_spot_bindings *c_get_switch_bindings (void);
 extern void c_release_switch_bindings (struct c_spot_bindings *);
 extern bool c_check_switch_jump_warnings (struct c_spot_bindings *,
                                          location_t, location_t);
-extern void c_maybe_initialize_eh (void);
 extern void finish_decl (tree, location_t, tree, tree, tree);
 extern tree finish_enum (tree, tree, tree);
 extern void finish_function (void);
@@ -589,9 +588,6 @@ extern int system_header_p;
 
 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);
index 2f5bd2a..75447be 100644 (file)
@@ -84,6 +84,7 @@ The callgraph:
 #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);
@@ -1953,6 +1954,12 @@ cgraph_add_new_function (tree fndecl, bool lowered)
        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.
index d6befec..a50e9fc 100644 (file)
@@ -1,3 +1,17 @@
+2009-09-13  Richard Guenther  <rguenther@suse.de>
+       Rafael Avila de Espindola  <espindola@google.com>
+
+       * 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.
+
 2009-09-13  Wei Guozhi  <carrot@google.com>
 
        PR c++/3187
index da5d8ac..861c93d 100644 (file)
@@ -250,7 +250,7 @@ cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \
   $(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
+  $(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 f818e5b..9521eab 100644 (file)
@@ -32,11 +32,14 @@ along with GCC; see the file COPYING3.  If not see
 #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.  */
@@ -71,6 +74,10 @@ static enum classify_record cp_classify_record (tree type);
 #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;
@@ -145,4 +152,26 @@ finish_file (void)
 {
 }
 
+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 ea3b4bf..c720a56 100644 (file)
@@ -4521,6 +4521,7 @@ extern void choose_personality_routine            (enum languages);
 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 fdef154..588c2ee 100644 (file)
@@ -43,7 +43,6 @@ along with GCC; see the file COPYING3.  If not see
 
 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);
@@ -78,15 +77,11 @@ init_exception_processing (void)
   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;
 }
 
@@ -143,7 +138,7 @@ eh_type_info (tree type)
 /* Build the address of a typeinfo decl for use in the runtime
    matching field of the exception model.  */
 
-static tree
+tree
 build_eh_type_type (tree type)
 {
   tree exp = eh_type_info (type);
@@ -313,7 +308,7 @@ decl_is_java_type (tree decl, int err)
 /* 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
+   ??? At present eh_personality_decl is set to
    __gxx_personality_(sj|v)0 in init_exception_processing - should it
    be done here instead?  */
 void
@@ -354,9 +349,7 @@ choose_personality_routine (enum languages lang)
     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");
+      pragma_java_exceptions = true;
       break;
 
     default:
index 62459e2..6f0b965 100644 (file)
@@ -216,6 +216,10 @@ static GTY(()) section *debug_str_section;
 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 ";#"
@@ -3599,6 +3603,7 @@ output_call_frame_info (int for_eh)
   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.  */
@@ -3684,6 +3689,8 @@ output_call_frame_info (int for_eh)
 
   augmentation[0] = 0;
   augmentation_size = 0;
+
+  personality = current_unit_personality;
   if (for_eh)
     {
       char *p;
@@ -3703,11 +3710,11 @@ output_call_frame_info (int for_eh)
       lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
 
       p = augmentation + 1;
-      if (eh_personality_libfunc)
+      if (personality)
        {
          *p++ = 'P';
          augmentation_size += 1 + size_of_encoded_value (per_encoding);
-         assemble_external_libcall (eh_personality_libfunc);
+         assemble_external_libcall (personality);
        }
       if (any_lsda_needed)
        {
@@ -3726,7 +3733,7 @@ output_call_frame_info (int for_eh)
        }
 
       /* Ug.  Some platforms can't do unaligned dynamic relocations at all.  */
-      if (eh_personality_libfunc && per_encoding == DW_EH_PE_aligned)
+      if (personality && per_encoding == DW_EH_PE_aligned)
        {
          int offset = (  4             /* Length */
                        + 4             /* CIE Id */
@@ -3760,12 +3767,12 @@ output_call_frame_info (int for_eh)
   if (augmentation[0])
     {
       dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size");
-      if (eh_personality_libfunc)
+      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,
-                                          eh_personality_libfunc,
+                                          personality,
                                           true, NULL);
        }
 
@@ -3824,13 +3831,14 @@ dwarf2out_do_cfi_startproc (bool second)
 {
   int enc;
   rtx ref;
+  rtx personality = get_personality_function (current_function_decl);
 
   fprintf (asm_out_file, "\t.cfi_startproc\n");
 
-  if (eh_personality_libfunc)
+  if (personality)
     {
       enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
-      ref = eh_personality_libfunc;
+      ref = personality;
 
       /* ??? The GAS support isn't entirely consistent.  We have to
         handle indirect support ourselves, but PC-relative is done
@@ -3873,6 +3881,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
   char label[MAX_ARTIFICIAL_LABEL_BYTES];
   char * dup_label;
   dw_fde_ref fde;
+  rtx personality;
   section *fnsec;
 
   current_function_func_begin_label = NULL;
@@ -3967,8 +3976,17 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
     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 c97928e..9b6c24e 100644 (file)
@@ -92,9 +92,6 @@ gimple (*lang_protect_cleanup_actions) (void);
 /* 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 {
@@ -1696,7 +1693,7 @@ add_type_for_runtime (tree type)
                                            TREE_HASH (type), INSERT);
   if (*slot == NULL)
     {
-      tree runtime = (*lang_eh_runtime_type) (type);
+      tree runtime = lang_hooks.eh_runtime_type (type);
       *slot = tree_cons (type, runtime, NULL_TREE);
     }
 }
@@ -2424,6 +2421,7 @@ sjlj_emit_function_enter (rtx dispatch_label)
 {
   rtx fn_begin, fc, mem, seq;
   bool fn_begin_outside_block;
+  rtx personality = get_personality_function (current_function_decl);
 
   fc = crtl->eh.sjlj_fc;
 
@@ -2432,9 +2430,9 @@ sjlj_emit_function_enter (rtx dispatch_label)
   /* 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);
+  assemble_external_libcall (personality);
   mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs);
-  emit_move_insn (mem, eh_personality_libfunc);
+  emit_move_insn (mem, personality);
 
   mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs);
   if (crtl->uses_eh_lsda)
@@ -4394,7 +4392,7 @@ output_ttype (tree type, int tt_format, int tt_format_size)
 
 static void
 output_one_function_exception_table (const char * ARG_UNUSED (fnname),
-                                    int section)
+                                    int section, rtx ARG_UNUSED (personality))
 {
   int tt_format, cs_format, lp_format, i, n;
 #ifdef HAVE_AS_LEB128
@@ -4410,7 +4408,7 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
 #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);
+  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.  */
@@ -4580,16 +4578,18 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname),
 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 (eh_personality_libfunc)
-    assemble_external_libcall (eh_personality_libfunc);
+  if (personality)
+    assemble_external_libcall (personality);
 
-  output_one_function_exception_table (fnname, 0);
+  output_one_function_exception_table (fnname, 0, personality);
   if (crtl->eh.call_site_record[1] != NULL)
-    output_one_function_exception_table (fnname, 1);
+    output_one_function_exception_table (fnname, 1, personality);
 
   switch_to_section (current_function_section ());
 }
@@ -4606,6 +4606,70 @@ get_eh_throw_stmt_table (struct function *fun)
   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 f332b2b..af63e98 100644 (file)
@@ -217,9 +217,6 @@ extern gimple (*lang_protect_cleanup_actions) (void);
 /* 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
@@ -277,3 +274,12 @@ extern int num_eh_regions (void);
 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 cd5eae1..be3b5bb 100644 (file)
@@ -10214,4 +10214,52 @@ const_vector_from_tree (tree exp)
 
   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 8eddb44..9bf0c38 100644 (file)
@@ -814,6 +814,12 @@ extern void init_all_optabs (void);
 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 903f25d..7cf6e86 100644 (file)
@@ -1,3 +1,9 @@
+2009-09-13  Richard Guenther  <rguenther@suse.de>
+       Rafael Avila de Espindola  <espindola@google.com>
+
+       * f95-lang.c (gfc_maybe_initialize_eh): Do not init
+       eh_personality_libfunc.
+
 2009-09-11  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/41242
index e061538..3d94fd6 100644 (file)
@@ -1155,10 +1155,6 @@ gfc_maybe_initialize_eh (void)
     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 ();
 }
index 569b5fe..6b7d930 100644 (file)
@@ -1,3 +1,13 @@
+2009-09-13  Richard Guenther  <rguenther@suse.de>
+       Rafael Avila de Espindola  <espindola@google.com>
+
+       * 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.
+
 2009-09-03  Diego Novillo  <dnovillo@google.com>
 
        * lang.c (lang_hooks): Remove const qualifier.
index ff330fd..a56e2b6 100644 (file)
@@ -284,7 +284,7 @@ java/jvgenmain.o: java/jvgenmain.c $(CONFIG_H) $(JAVA_TREE_H) $(SYSTEM_H) \
   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
+  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 4ab67d6..c9ccc9d 100644 (file)
@@ -510,12 +510,6 @@ create_primitive_vtable (const char *name)
   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)
@@ -1195,16 +1189,12 @@ java_init_decl_processing (void)
                            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];
 
index d97b508..504d029 100644 (file)
@@ -45,6 +45,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "tree-dump.h"
 #include "opts.h"
 #include "options.h"
+#include "except.h"
 
 static bool java_init (void);
 static void java_finish (void);
@@ -64,6 +65,8 @@ static bool java_decl_ok_for_sibcall (const_tree);
 
 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
@@ -158,6 +161,9 @@ struct GTY(()) language_function {
 #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;
 
@@ -880,4 +886,18 @@ java_classify_record (tree type)
   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 63a0dcd..dc4fdee 100644 (file)
@@ -40,6 +40,7 @@ extern void lhd_do_nothing (void);
 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);
@@ -107,6 +108,8 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *,
 #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_EH_PERSONALITY      lhd_gcc_personality
+#define LANG_HOOKS_EH_RUNTIME_TYPE     lhd_pass_through_t
 
 /* Attribute hooks.  */
 #define LANG_HOOKS_ATTRIBUTE_TABLE             NULL
@@ -271,6 +274,8 @@ extern tree lhd_make_node (enum tree_code);
   LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \
   LANG_HOOKS_INIT_TS,          \
   LANG_HOOKS_EXPR_TO_DECL, \
+  LANG_HOOKS_EH_PERSONALITY, \
+  LANG_HOOKS_EH_RUNTIME_TYPE, \
 }
 
 #endif /* GCC_LANG_HOOKS_DEF_H */
index 7d2c0b0..092a323 100644 (file)
@@ -53,6 +53,13 @@ lhd_do_nothing_t (tree ARG_UNUSED (t))
 {
 }
 
+/* Pass through (tree).  */
+tree
+lhd_pass_through_t (tree t)
+{
+  return t;
+}
+
 /* Do nothing (int).  */
 
 void
index 8342004..349a5d8 100644 (file)
@@ -414,6 +414,12 @@ struct lang_hooks
      if in the process TREE_CONSTANT or TREE_SIDE_EFFECTS need updating.  */
   tree (*expr_to_decl) (tree expr, bool *tc, bool *se);
 
+  /* 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 70621cf..997ecb0 100644 (file)
@@ -31,7 +31,6 @@ enum libfunc_index
   LTI_setbits,
 
   LTI_unwind_resume,
-  LTI_eh_personality,
   LTI_setjmp,
   LTI_longjmp,
   LTI_unwind_sjlj_register,
@@ -61,7 +60,6 @@ extern GTY(()) rtx libfunc_table[LTI_MAX];
 #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])
index d499f0a..59317eb 100644 (file)
@@ -1,3 +1,17 @@
+2009-09-13  Richard Guenther  <rguenther@suse.de>
+       Rafael Avila de Espindola  <espindola@google.com>
+
+       * objc-act.c (objc_eh_runtime_type): Export.
+       (objc_init_exceptions): Remove.  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_eh_runtime_type): Declare.
+       (objc_eh_personality): Likewise.
+       * objc-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define.
+       (LANG_HOOKS_EH_PERSONALITY): Likewise.
+
 2009-09-03  Diego Novillo  <dnovillo@google.com>
 
        * objc-lang.c (lang_hooks): Remove const qualifier.
index 8b1a596..f695431 100644 (file)
@@ -3483,50 +3483,32 @@ struct objc_try_context
 
 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
-static tree
+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)
+tree
+objc_eh_personality (void)
 {
-  static bool done = false;
-  if (done)
-    return;
-  done = true;
+  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");
 
-  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
+  return objc_eh_personality_decl;
 }
+#endif
 
 /* Build an EXC_PTR_EXPR, or the moral equivalent.  In the case of Darwin,
    we'll arrange for it to be initialized (and associated with a binding)
@@ -3824,7 +3806,14 @@ objc_begin_try_stmt (location_t try_locus, tree body)
   c->end_try_locus = input_location;
   cur_try_context = c;
 
-  objc_init_exceptions ();
+  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);
@@ -3973,7 +3962,14 @@ objc_build_throw_stmt (location_t loc, tree throw_expr)
 {
   tree args;
 
-  objc_init_exceptions ();
+  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 fb92934..f0970f9 100644 (file)
@@ -32,6 +32,8 @@ const char *objc_printable_name (tree, int);
 void objc_finish_file (void);
 tree objc_fold_obj_type_ref (tree, tree);
 int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *);
+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 98f46d7..acb1c84 100644 (file)
@@ -51,6 +51,13 @@ static void objc_init_ts (void);
 #undef LANG_HOOKS_INIT_TS
 #define LANG_HOOKS_INIT_TS objc_init_ts
 
+#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 61d8bcf..35f95f2 100644 (file)
@@ -6023,6 +6023,28 @@ libfunc_decl_eq (const void *entry1, const void *entry2)
   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)
 {
@@ -6043,19 +6065,7 @@ init_one_libfunc (const char *name)
     {
       /* 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);
-
+      decl = build_libfunc_function (name);
       *slot = decl;
     }
   return XEXP (DECL_RTL (decl), 0);
index d9baf71..ac87f42 100644 (file)
@@ -1939,6 +1939,14 @@ lower_eh_constructs (void)
   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 b5e7346..b83c52f 100644 (file)
@@ -3505,6 +3505,13 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
 
   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))
@@ -3546,6 +3553,11 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
   /* 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;
@@ -4730,6 +4742,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
 
   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));
@@ -5000,6 +5013,18 @@ tree_can_inline_p (struct cgraph_edge *e)
   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 27ab46c..98a683d 100644 (file)
@@ -10566,5 +10566,20 @@ tree_strip_sign_nop_conversions (tree exp)
   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 45391d3..5884b55 100644 (file)
@@ -2538,6 +2538,9 @@ struct GTY(()) tree_decl_minimal {
 #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.  Moreover, for a FUNCTION_DECL,
    the body of the function should also be ignored.  */
@@ -3191,6 +3194,9 @@ struct GTY(()) tree_function_decl {
 
   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 */
@@ -4653,6 +4659,7 @@ extern bool auto_var_in_fn_p (const_tree, const_tree);
 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);
@@ -5264,6 +5271,7 @@ extern unsigned HOST_WIDE_INT compute_builtin_object_size (tree, int);
 
 /* In expr.c.  */
 extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
+extern tree build_personality_function (const char *);
 
 /* In tree-inline.c.  */