aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@gcc.gnu.org>2002-04-19 23:02:52 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2002-04-19 23:02:52 +0200
commitce5e43d03eab3681671efc777b479a5855dc5906 (patch)
tree0e838c68b72f69376a107d82f90a16743deefc37 /gcc/function.c
parent9eb83f6ce767092711c8c54fb766129c6d4c5a79 (diff)
downloadgcc-ce5e43d03eab3681671efc777b479a5855dc5906.zip
gcc-ce5e43d03eab3681671efc777b479a5855dc5906.tar.gz
gcc-ce5e43d03eab3681671efc777b479a5855dc5906.tar.bz2
re PR c/6358 (GCC 3.1 ICE on statement expressions)
PR c/6358 * function.c: Reapply patch for c/6358. (expand_function_end): Copy decl_rtl's mode, not current_function_return_rtx mode. From-SVN: r52538
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c49
1 files changed, 34 insertions, 15 deletions
diff --git a/gcc/function.c b/gcc/function.c
index 86a87ab..ab3654a 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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,23 +6987,18 @@ 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
decl_rtl is memory, then its mode may have been changed,
but that current_function_return_rtx has not. */
if (GET_MODE (real_decl_rtl) == BLKmode)
- PUT_MODE (real_decl_rtl, GET_MODE (current_function_return_rtx));
+ PUT_MODE (real_decl_rtl, GET_MODE (decl_rtl));
/* If a named return value dumped decl_return to memory, then
we may need to re-do the PROMOTE_MODE signed/unsigned
@@ -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;
}
}