aboutsummaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-04-22 05:44:12 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-04-22 05:44:12 +0000
commitb2dd096b0c7e5c48380b99b3d2b1ff4763b7f525 (patch)
tree0b42d76e5fdf7dbe6a765ae20af65b5a2ed24e6d /gcc/except.c
parentf71c12554b607c5980b932a4dff5cba4c7decb89 (diff)
downloadgcc-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.c66
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. */