summaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-01-15 09:07:38 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2009-01-15 09:07:38 +0100
commit0196c95ed418b0cd0f6c648018da34f947a76e90 (patch)
treedf30f7de379a5cadc80eb495456de5a3b9f9d10b /gcc/calls.c
parent6df6bcfa0fde9cc6413088d609f799188444f51b (diff)
downloadgcc-0196c95ed418b0cd0f6c648018da34f947a76e90.tar.gz
re PR rtl-optimization/38245 (stack corruption when a call is removed but not the outgoing argument pushes)
PR rtl-optimization/38245 * calls.c (expand_call): Add stack arguments to CALL_INSN_FUNCTION_USAGE even for pure calls (when ACCUMULATE_OUTGOING_ARGS) and even for args partially passed in regs and partially in memory or BLKmode arguments. (emit_library_call_value_1): Add stack arguments to CALL_INSN_FUNCTION_USAGE even for pure calls (when ACCUMULATE_OUTGOING_ARGS). * dce.c: Include tm_p.h. (find_call_stack_args): New function. (deletable_insn_p): Call it for CALL_P insns. Add ARG_STORES argument. (mark_insn): Call find_call_stack_args for CALL_Ps. (prescan_insns_for_dce): Walk insns backwards in bb rather than forwards. Allocate and free arg_stores bitmap if needed, pass it down to deletable_insn_p, don't mark stores set in arg_stores bitmap, clear the bitmap at the beginning of each bb. * Makefile.in (dce.o): Depend on $(TM_P_H). * gcc.dg/pr38245-3.c: New test. * gcc.dg/pr38245-3.h: New file. * gcc.dg/pr38245-4.c: New file. * gcc.dg/pr38364.c: New test. From-SVN: r143387
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index f6bc970b71b..a75e3b36569 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1,6 +1,6 @@
/* Convert function calls to rtl insns, for GNU C compiler.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GCC.
@@ -2705,26 +2705,28 @@ expand_call (tree exp, rtx target, int ignore)
but we do preallocate space here if they want that. */
for (i = 0; i < num_actuals; i++)
- if (args[i].reg == 0 || args[i].pass_on_stack)
- {
- rtx before_arg = get_last_insn ();
-
- if (store_one_arg (&args[i], argblock, flags,
- adjusted_args_size.var != 0,
- reg_parm_stack_space)
- || (pass == 0
- && check_sibcall_argument_overlap (before_arg,
- &args[i], 1)))
- sibcall_failure = 1;
-
- if (flags & ECF_CONST
- && args[i].stack
- && args[i].value == args[i].stack)
- call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
- gen_rtx_USE (VOIDmode,
- args[i].value),
- call_fusage);
- }
+ {
+ if (args[i].reg == 0 || args[i].pass_on_stack)
+ {
+ rtx before_arg = get_last_insn ();
+
+ if (store_one_arg (&args[i], argblock, flags,
+ adjusted_args_size.var != 0,
+ reg_parm_stack_space)
+ || (pass == 0
+ && check_sibcall_argument_overlap (before_arg,
+ &args[i], 1)))
+ sibcall_failure = 1;
+ }
+
+ if (((flags & ECF_CONST)
+ || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS))
+ && args[i].stack)
+ call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
+ gen_rtx_USE (VOIDmode,
+ args[i].stack),
+ call_fusage);
+ }
/* If we have a parm that is passed in registers but not in memory
and whose alignment does not permit a direct copy into registers,
@@ -3672,7 +3674,8 @@ emit_library_call_value_1 (int retval, rtx orgfun, rtx value,
NO_DEFER_POP;
- if (flags & ECF_CONST)
+ if ((flags & ECF_CONST)
+ || ((flags & ECF_PURE) && ACCUMULATE_OUTGOING_ARGS))
{
rtx use;