calls.c (store_arg): Return non-zero if sibcall_failure is desired.

* calls.c (store_arg): Return non-zero if sibcall_failure is
	desired.
	(expand_call): Adjust caller.
	* gcc.c-torture/execute/20000717-5.c: New test.
	* gcc.c-torture/execute/20000717-1.x: Removed.

From-SVN: r35117
This commit is contained in:
Jakub Jelinek 2000-07-18 10:54:33 +02:00
parent e81b4d6305
commit 4c6b3b2af0
5 changed files with 95 additions and 21 deletions

View File

@ -1,3 +1,9 @@
2000-07-18 Jakub Jelinek <jakub@redhat.com>
* calls.c (store_arg): Return non-zero if sibcall_failure is
desired.
(expand_call): Adjust caller.
2000-07-17 Gabriel Dos Reis <gdr@codesourcery.com>
* diagnostic.h (report_diagnostic): Change prototype.
@ -14,7 +20,7 @@
* c-errors.c (pedwarn_c99): Adjust call to report_diagnostic. End
varaible argument list.
2000-02-17 Zack Weinberg <zack@wolery.cumb.org>
2000-07-17 Zack Weinberg <zack@wolery.cumb.org>
* cpphash.c: Don't include hashtab.h. Most macro-handling code
moved to cppmacro.c.
@ -41,7 +47,7 @@
* cppmain.c: Do not set pfile->printer if no_output is on.
2000-02-15 Neil Booth <neilb@earthling.net>
2000-07-15 Neil Booth <neilb@earthling.net>
* cpplib.c: Change all directive-handler functions to return
void, not int.

View File

@ -191,7 +191,7 @@ static void emit_call_1 PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
static void precompute_register_parameters PARAMS ((int,
struct arg_data *,
int *));
static void store_one_arg PARAMS ((struct arg_data *, rtx, int, int,
static int store_one_arg PARAMS ((struct arg_data *, rtx, int, int,
int));
static void store_unaligned_arguments_into_pseudos PARAMS ((struct arg_data *,
int));
@ -1952,10 +1952,10 @@ check_sibcall_argument_overlap_1 (x)
{
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)
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
return 0;
@ -2947,10 +2947,12 @@ expand_call (exp, target, ignore)
{
rtx before_arg = get_last_insn ();
store_one_arg (&args[i], argblock, flags,
adjusted_args_size.var != 0, reg_parm_stack_space);
if (pass == 0 &&
check_sibcall_argument_overlap (before_arg, &args[i]))
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])))
sibcall_failure = 1;
}
@ -2969,10 +2971,12 @@ expand_call (exp, target, ignore)
{
rtx before_arg = get_last_insn ();
store_one_arg (&args[i], argblock, flags,
adjusted_args_size.var != 0, reg_parm_stack_space);
if (pass == 0 &&
check_sibcall_argument_overlap (before_arg, &args[i]))
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])))
sibcall_failure = 1;
}
@ -4218,9 +4222,12 @@ target_for_arg (type, size, args_addr, offset)
argument stack. This is used if ACCUMULATE_OUTGOING_ARGS to indicate
that we need not worry about saving and restoring the stack.
FNDECL is the declaration of the function we are calling. */
FNDECL is the declaration of the function we are calling.
Return non-zero if this arg should cause sibcall failure,
zero otherwise. */
static void
static int
store_one_arg (arg, argblock, flags, variable_size,
reg_parm_stack_space)
struct arg_data *arg;
@ -4234,9 +4241,10 @@ store_one_arg (arg, argblock, flags, variable_size,
int partial = 0;
int used = 0;
int i, lower_bound = 0, upper_bound = 0;
int sibcall_failure = 0;
if (TREE_CODE (pval) == ERROR_MARK)
return;
return 1;
/* Push a new temporary level for any temporaries we make for
this argument. */
@ -4451,6 +4459,39 @@ store_one_arg (arg, argblock, flags, variable_size,
size_rtx = expr_size (pval);
}
if ((flags & ECF_SIBCALL) && GET_CODE (arg->value) == MEM)
{
/* emit_push_insn might not work properly if arg->value and
argblock + arg->offset areas overlap. */
rtx x = arg->value;
int i = 0;
if (XEXP (x, 0) == current_function_internal_arg_pointer
|| (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))
{
if (XEXP (x, 0) != current_function_internal_arg_pointer)
i = INTVAL (XEXP (XEXP (x, 0), 1));
/* expand_call should ensure this */
if (arg->offset.var || GET_CODE (size_rtx) != CONST_INT)
abort ();
if (arg->offset.constant > i)
{
if (arg->offset.constant < i + INTVAL (size_rtx))
sibcall_failure = 1;
}
else if (arg->offset.constant < i)
{
if (i < arg->offset.constant + INTVAL (size_rtx))
sibcall_failure = 1;
}
}
}
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
TYPE_ALIGN (TREE_TYPE (pval)), partial, reg, excess,
argblock, ARGS_SIZE_RTX (arg->offset),
@ -4482,4 +4523,6 @@ store_one_arg (arg, argblock, flags, variable_size,
preserve_temp_slots (NULL_RTX);
free_temp_slots ();
pop_temp_slots ();
return sibcall_failure;
}

View File

@ -1,3 +1,8 @@
2000-07-18 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/20000717-5.c: New test.
* gcc.c-torture/execute/20000717-1.x: Removed.
2000-07-17 Richard Henderson <rth@cygnus.com>
* gcc.c-torture/execute/20000717-4.c: New test.

View File

@ -1,3 +0,0 @@
set torture_execute_xfail "*-*-*"
return 0

View File

@ -0,0 +1,23 @@
typedef struct trio { int a, b, c; } trio;
int
bar (int i, int j, int k, trio t)
{
if (t.a != 1 || t.b != 2 || t.c != 3 ||
i != 4 || j != 5 || k != 6)
abort ();
}
int
foo (trio t, int i, int j, int k)
{
return bar (i, j, k, t);
}
main ()
{
trio t = { 1, 2, 3 };
foo (t, 4, 5, 6);
exit (0);
}