aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index 21feeed..104cc07 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2020,7 +2020,8 @@ expand_call (exp, target, ignore)
safe_for_reeval = 0;
if (optimize >= 2
&& currently_expanding_call == 1
- && stmt_loop_nest_empty ())
+ && stmt_loop_nest_empty ()
+ && ! any_pending_cleanups (1))
{
/* Verify that each argument is safe for re-evaluation. */
for (p = actparms; p; p = TREE_CHAIN (p))
@@ -2152,6 +2153,12 @@ expand_call (exp, target, ignore)
|| ! FUNCTION_OK_FOR_SIBCALL (fndecl))
continue;
+ /* We know at this point that there are not currently any
+ pending cleanups. If, however, in the process of evaluating
+ the arguments we were to create some, we'll need to be
+ able to get rid of them. */
+ expand_start_target_temps ();
+
/* State variables we need to save and restore between
iterations. */
save_pending_stack_adjust = pending_stack_adjust;
@@ -2925,6 +2932,14 @@ expand_call (exp, target, ignore)
if (args[i].aligned_regs)
free (args[i].aligned_regs);
+ if (pass == 0)
+ {
+ /* Undo the fake expand_start_target_temps we did earlier. If
+ there had been any cleanups created, we've already set
+ sibcall_failure. */
+ expand_end_target_temps ();
+ }
+
insns = get_insns ();
end_sequence ();