re PR c/6358 (GCC 3.1 ICE on statement expressions)

PR c/6358
	* function.c (assign_parms): Assign hard current_function_return_rtx
	register here...
	(expand_function_end): ...not here.

	* gcc.c-torture/compile/20020418-1.c: New test.

From-SVN: r52485
This commit is contained in:
Jakub Jelinek 2002-04-18 21:10:11 +02:00 committed by Jakub Jelinek
parent 8ecab453cb
commit a3acf46d44
4 changed files with 62 additions and 14 deletions

View File

@ -1,3 +1,10 @@
2002-04-18 Jakub Jelinek <jakub@redhat.com>
PR c/6358
* function.c (assign_parms): Assign hard current_function_return_rtx
register here...
(expand_function_end): ...not here.
2002-04-18 Neil Booth <neil@daikokuya.demon.co.uk>
* c-lang.c (LANG_HOOKS_INCOMPLETE_TYPE_ERROR): Redefine.

View File

@ -5145,6 +5145,35 @@ assign_parms (fndecl)
current_function_return_rtx
= (DECL_RTL_SET_P (DECL_RESULT (fndecl))
? DECL_RTL (DECL_RESULT (fndecl)) : NULL_RTX);
/* If scalar return value was computed in a pseudo-reg, or was a named
return value that got dumped to the stack, copy that to the hard
return register. */
if (DECL_RTL_SET_P (DECL_RESULT (fndecl)))
{
tree decl_result = DECL_RESULT (fndecl);
rtx decl_rtl = DECL_RTL (decl_result);
if (REG_P (decl_rtl)
? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
: DECL_REGISTER (decl_result))
{
rtx real_decl_rtl;
#ifdef FUNCTION_OUTGOING_VALUE
real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
fndecl);
#else
real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
fndecl);
#endif
REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
/* The delay slot scheduler assumes that current_function_return_rtx
holds the hard register containing the return value, not a
temporary pseudo. */
current_function_return_rtx = real_decl_rtl;
}
}
}
/* Indicate whether REGNO is an incoming argument to the current function
@ -6958,16 +6987,11 @@ expand_function_end (filename, line, end_bindings)
? REGNO (decl_rtl) >= FIRST_PSEUDO_REGISTER
: DECL_REGISTER (decl_result))
{
rtx real_decl_rtl;
rtx real_decl_rtl = current_function_return_rtx;
#ifdef FUNCTION_OUTGOING_VALUE
real_decl_rtl = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl_result),
current_function_decl);
#else
real_decl_rtl = FUNCTION_VALUE (TREE_TYPE (decl_result),
current_function_decl);
#endif
REG_FUNCTION_VALUE_P (real_decl_rtl) = 1;
/* This should be set in assign_parms. */
if (! REG_FUNCTION_VALUE_P (real_decl_rtl))
abort ();
/* If this is a BLKmode structure being returned in registers,
then use the mode computed in expand_return. Note that if
@ -6995,11 +7019,6 @@ expand_function_end (filename, line, end_bindings)
int_size_in_bytes (TREE_TYPE (decl_result)));
else
emit_move_insn (real_decl_rtl, decl_rtl);
/* The delay slot scheduler assumes that current_function_return_rtx
holds the hard register containing the return value, not a
temporary pseudo. */
current_function_return_rtx = real_decl_rtl;
}
}

View File

@ -1,3 +1,7 @@
2002-04-18 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/compile/20020418-1.c: New test.
2002-04-18 Roger Sayle <roger@eyesopen.com>
* gcc.c-torture/compile/20020415-1.c: New.

View File

@ -0,0 +1,18 @@
/* PR c/6358
This testcase ICEd on IA-32 in foo, because current_function_return_rtx
was assigned a hard register only after expand_null_return was called,
thus return pseudo was clobbered twice and the hard register not at
all. */
void baz (void);
double foo (void)
{
baz ();
return;
}
double bar (void)
{
baz ();
}