diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-07-25 09:54:07 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-07-25 09:54:07 +0200 |
commit | 0dc42b03d364d14f6e31d4021201f8a1d6323da6 (patch) | |
tree | a7f628578c0ccef5e4f29a6a9c7f07ba9b4a9bc9 /gcc/calls.c | |
parent | 31f74accb27dfe58e1926dbbcb0b9d57e55bde42 (diff) | |
download | gcc-0dc42b03d364d14f6e31d4021201f8a1d6323da6.zip gcc-0dc42b03d364d14f6e31d4021201f8a1d6323da6.tar.gz gcc-0dc42b03d364d14f6e31d4021201f8a1d6323da6.tar.bz2 |
calls.c (store_one_arg): Check for sibling call MEM arguments from already clobbered incoming argument area.
* calls.c (store_one_arg): Check for sibling call MEM arguments
from already clobbered incoming argument area.
* gcc.c-torture/execute/20050713-1.c: New test.
From-SVN: r102350
Diffstat (limited to 'gcc/calls.c')
-rw-r--r-- | gcc/calls.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/gcc/calls.c b/gcc/calls.c index 8e87886..ea6eaeb 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -4076,6 +4076,38 @@ store_one_arg (struct arg_data *arg, rtx argblock, int flags, stack_arg_under_construction--; } + /* Check for overlap with already clobbered argument area. */ + if ((flags & ECF_SIBCALL) && MEM_P (arg->value)) + { + int i = -1; + unsigned int k; + rtx x = arg->value; + + if (XEXP (x, 0) == current_function_internal_arg_pointer) + i = 0; + else if (GET_CODE (XEXP (x, 0)) == PLUS + && XEXP (XEXP (x, 0), 0) == + current_function_internal_arg_pointer + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT) + i = INTVAL (XEXP (XEXP (x, 0), 1)); + else + i = -1; + + if (i >= 0) + { +#ifdef ARGS_GROW_DOWNWARD + i = -i - arg->locate.size.constant; +#endif + for (k = 0; k < arg->locate.size.constant; k++) + if (i + k < stored_args_map->n_bits + && TEST_BIT (stored_args_map, i + k)) + { + sibcall_failure = 1; + break; + } + } + } + /* Don't allow anything left on stack from computation of argument to alloca. */ if (flags & ECF_MAY_BE_ALLOCA) |