Commit 0dc42b03 by Jakub Jelinek Committed by Jakub Jelinek

calls.c (store_one_arg): Check for sibling call MEM arguments from already…

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
parent 31f74acc
2005-07-25 Jakub Jelinek <jakub@redhat.com>
* calls.c (store_one_arg): Check for sibling call MEM arguments
from already clobbered incoming argument area.
2005-07-24 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* c-common.c (check_missing_format_attribute): New.
......
......@@ -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)
......
2005-07-25 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20050713-1.c: New test.
PR fortran/20063
* gfortran.fortran-torture/execute/data_4.f90: New test.
......
/* Test that sibling call is not used if there is an argument overlap. */
extern void abort (void);
struct S
{
int a, b, c;
};
int
foo2 (struct S x, struct S y)
{
if (x.a != 3 || x.b != 4 || x.c != 5)
abort ();
if (y.a != 6 || y.b != 7 || y.c != 8)
abort ();
return 0;
}
int
foo3 (struct S x, struct S y, struct S z)
{
foo2 (x, y);
if (z.a != 9 || z.b != 10 || z.c != 11)
abort ();
return 0;
}
int
bar2 (struct S x, struct S y)
{
return foo2 (y, x);
}
int
bar3 (struct S x, struct S y, struct S z)
{
return foo3 (y, x, z);
}
int
baz3 (struct S x, struct S y, struct S z)
{
return foo3 (y, z, x);
}
int
main (void)
{
struct S a = { 3, 4, 5 }, b = { 6, 7, 8 }, c = { 9, 10, 11 };
bar2 (b, a);
bar3 (b, a, c);
baz3 (c, a, b);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment