summaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-29 22:58:23 +0000
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-29 22:58:23 +0000
commit43926c6a3ad12927b879bd6591f3e1012d743146 (patch)
tree65663b47ff72f52cbcb2aeb91f37bdce44a408c9 /gcc/calls.c
parentbf330a11be325d339866f3c2f26c2482859117c4 (diff)
downloadgcc-43926c6a3ad12927b879bd6591f3e1012d743146.tar.gz
PR middle-end/55321
* calls.c (emit_library_call_value_1): Mark as no-nonlocal if no-throw. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193973 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index f4bed747e84..574c247f0e5 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -4196,13 +4196,11 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
that it should complain if nonvolatile values are live. For
functions that cannot return, inform flow that control does not
fall through. */
-
if (flags & ECF_NORETURN)
{
/* The barrier note must be emitted
immediately after the CALL_INSN. Some ports emit more than
just a CALL_INSN above, so we must search for it here. */
-
rtx last = get_last_insn ();
while (!CALL_P (last))
{
@@ -4214,6 +4212,21 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
emit_barrier_after (last);
}
+ /* Consider that "regular" libcalls, i.e. all of them except for LCT_THROW
+ and LCT_RETURNS_TWICE, cannot perform non-local gotos. */
+ if (flags & ECF_NOTHROW)
+ {
+ rtx last = get_last_insn ();
+ while (!CALL_P (last))
+ {
+ last = PREV_INSN (last);
+ /* There was no CALL_INSN? */
+ gcc_assert (last != before_call);
+ }
+
+ make_reg_eh_region_note_nothrow_nononlocal (last);
+ }
+
/* Now restore inhibit_defer_pop to its actual original value. */
OK_DEFER_POP;