diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-04-22 05:44:12 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-04-22 05:44:12 +0000 |
commit | b2dd096b0c7e5c48380b99b3d2b1ff4763b7f525 (patch) | |
tree | 0b42d76e5fdf7dbe6a765ae20af65b5a2ed24e6d /gcc/except.c | |
parent | f71c12554b607c5980b932a4dff5cba4c7decb89 (diff) | |
download | gcc-b2dd096b0c7e5c48380b99b3d2b1ff4763b7f525.zip gcc-b2dd096b0c7e5c48380b99b3d2b1ff4763b7f525.tar.gz gcc-b2dd096b0c7e5c48380b99b3d2b1ff4763b7f525.tar.bz2 |
Makefile.in (calls.o): Depend on except.h.
* Makefile.in (calls.o): Depend on except.h.
* calls.c: Include except.h.
(emit_call_1): Call note_eh_region_may_contain_throw if
appropriate.
* except.c (eh_region): Add may_contain_throw.
(expand_eh_region_end_cleanup): Do not include handler code when
it cannot be reached.
(note_eh_region_may_contain_throw): New function.
* except.h (note_eh_region_may_contain_throw): New function.
* call.c (build_over_call): Use build_cxx_call.
(build_cxx_call): New method, split out of build_over_call.
* cp-tree.h (language_function): Add can_throw.
(build_cxx_call): Declare it.
* decl.c (finish_function): If a function does not contain any
calls to functions that can throw an exception, indicate that
fact.
* decl2.c (mark_used): Do not defer the instantiation of
functions, if the current function does not throw.
* optimize.c (maybe_clone_body): Copy TREE_NOTHROW to the clones.
* pt.c (instantiate_decl): Make sure import_export_decl is called
before emitting things.
* rtti.c (throw_bad_cast): Use build_cxx_call.
(build_dynamic_cast_1): Likewise.
* typeck.c (build_function_call): Likewise.
* g++.dg/template/recurse.C: Adjust location of error messages.
From-SVN: r65929
Diffstat (limited to 'gcc/except.c')
-rw-r--r-- | gcc/except.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/gcc/except.c b/gcc/except.c index a999834..afc6a01 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -209,6 +209,9 @@ struct eh_region GTY(()) /* The RESX insn for handing off control to the next outermost handler, if appropriate. */ rtx resume; + + /* True if something in this region may throw. */ + unsigned may_contain_throw : 1; }; struct call_site_record GTY(()) @@ -561,33 +564,38 @@ expand_eh_region_end_cleanup (handler) emit_label (region->label); - /* Give the language a chance to specify an action to be taken if an - exception is thrown that would propagate out of the HANDLER. */ - protect_cleanup_actions - = (lang_protect_cleanup_actions - ? (*lang_protect_cleanup_actions) () - : NULL_TREE); + if (flag_non_call_exceptions + || flag_forced_unwind_exceptions + || region->may_contain_throw) + { + /* Give the language a chance to specify an action to be taken if an + exception is thrown that would propagate out of the HANDLER. */ + protect_cleanup_actions + = (lang_protect_cleanup_actions + ? (*lang_protect_cleanup_actions) () + : NULL_TREE); - if (protect_cleanup_actions) - expand_eh_region_start (); + if (protect_cleanup_actions) + expand_eh_region_start (); - /* In case this cleanup involves an inline destructor with a try block in - it, we need to save the EH return data registers around it. */ - data_save[0] = gen_reg_rtx (ptr_mode); - emit_move_insn (data_save[0], get_exception_pointer (cfun)); - data_save[1] = gen_reg_rtx (word_mode); - emit_move_insn (data_save[1], get_exception_filter (cfun)); + /* In case this cleanup involves an inline destructor with a try block in + it, we need to save the EH return data registers around it. */ + data_save[0] = gen_reg_rtx (ptr_mode); + emit_move_insn (data_save[0], get_exception_pointer (cfun)); + data_save[1] = gen_reg_rtx (word_mode); + emit_move_insn (data_save[1], get_exception_filter (cfun)); - expand_expr (handler, const0_rtx, VOIDmode, 0); + expand_expr (handler, const0_rtx, VOIDmode, 0); - emit_move_insn (cfun->eh->exc_ptr, data_save[0]); - emit_move_insn (cfun->eh->filter, data_save[1]); + emit_move_insn (cfun->eh->exc_ptr, data_save[0]); + emit_move_insn (cfun->eh->filter, data_save[1]); - if (protect_cleanup_actions) - expand_eh_region_end_must_not_throw (protect_cleanup_actions); + if (protect_cleanup_actions) + expand_eh_region_end_must_not_throw (protect_cleanup_actions); - /* We need any stack adjustment complete before the around_label. */ - do_pending_stack_adjust (); + /* We need any stack adjustment complete before the around_label. */ + do_pending_stack_adjust (); + } /* We delay the generation of the _Unwind_Resume until we generate landing pads. We emit a marker here so as to get good control @@ -823,6 +831,22 @@ expand_eh_region_end_fixup (handler) fixup->u.fixup.cleanup_exp = handler; } +/* Note that the current EH region (if any) may contain a throw, or a + call to a function which itself may contain a throw. */ + +void +note_eh_region_may_contain_throw () +{ + struct eh_region *region; + + region = cfun->eh->cur_region; + while (region && !region->may_contain_throw) + { + region->may_contain_throw = 1; + region = region->outer; + } +} + /* Return an rtl expression for a pointer to the exception object within a handler. */ |