diff options
Diffstat (limited to 'gcc/except.c')
-rw-r--r-- | gcc/except.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/gcc/except.c b/gcc/except.c index 7ecfaf85c21..987305a3798 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -1646,16 +1646,7 @@ expand_fixup_region_end (cleanup) } /* If we are using the setjmp/longjmp EH codegen method, we emit a - call to __sjthrow. - - Otherwise, we emit a call to __throw and note that we threw - something, so we know we need to generate the necessary code for - __throw. - - Before invoking throw, the __eh_pc variable must have been set up - to contain the PC being thrown from. This address is used by - __throw to determine which exception region (if any) is - responsible for handling the exception. */ + call to __sjthrow. Otherwise, we emit a call to __throw. */ void emit_throw () @@ -2629,6 +2620,10 @@ static int can_throw (insn) rtx insn; { + if (GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == SEQUENCE) + insn = XVECEXP (PATTERN (insn), 0, 0); + /* Calls can always potentially throw exceptions, unless they have a REG_EH_REGION note with a value of 0 or less. */ if (GET_CODE (insn) == CALL_INSN) @@ -2649,6 +2644,24 @@ can_throw (insn) return 0; } +/* Return nonzero if nothing in this function can throw. */ + +int +nothrow_function_p () +{ + rtx insn; + + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if (can_throw (insn)) + return 0; + for (insn = current_function_epilogue_delay_list; insn; + insn = XEXP (insn, 1)) + if (can_throw (insn)) + return 0; + + return 1; +} + /* Scan a exception region looking for the matching end and then remove it if possible. INSN is the start of the region, N is the region number, and DELETE_OUTER is to note if anything in this |