aboutsummaryrefslogtreecommitdiff
path: root/gcc/function.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/function.c')
-rw-r--r--gcc/function.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/gcc/function.c b/gcc/function.c
index d81e8b1ba8a..ebc7eda1604 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2477,8 +2477,7 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
/* If the parm is to be passed as a transparent union or record, use the
type of the first field for the tests below. We have already verified
that the modes are the same. */
- if ((TREE_CODE (passed_type) == UNION_TYPE
- || TREE_CODE (passed_type) == RECORD_TYPE)
+ if (RECORD_OR_UNION_TYPE_P (passed_type)
&& TYPE_TRANSPARENT_AGGR (passed_type))
passed_type = TREE_TYPE (first_field (passed_type));
@@ -3098,7 +3097,7 @@ assign_parm_setup_block (struct assign_parm_data_all *all,
move_block_from_reg (REGNO (entry_parm), mem,
size_stored / UNITS_PER_WORD);
}
- else if (data->stack_parm == 0)
+ else if (data->stack_parm == 0 && !TYPE_EMPTY_P (data->passed_type))
{
push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn);
emit_block_move (stack_parm, data->entry_parm, GEN_INT (size),
@@ -3474,7 +3473,9 @@ assign_parm_setup_stack (struct assign_parm_data_all *all, tree parm,
dest = validize_mem (copy_rtx (data->stack_parm));
src = validize_mem (copy_rtx (data->entry_parm));
- if (MEM_P (src))
+ if (TYPE_EMPTY_P (data->passed_type))
+ /* Empty types don't really need to be copied. */;
+ else if (MEM_P (src))
{
/* Use a block move to handle potentially misaligned entry_parm. */
if (!to_conversion)
@@ -3749,6 +3750,16 @@ assign_parms (tree fndecl)
{
assign_parm_find_stack_rtl (parm, &data);
assign_parm_adjust_entry_rtl (&data);
+ /* For arguments that occupy no space in the parameter
+ passing area, have non-zero size and have address taken,
+ force creation of a stack slot so that they have distinct
+ address from other parameters. */
+ if (TYPE_EMPTY_P (data.passed_type)
+ && TREE_ADDRESSABLE (parm)
+ && data.entry_parm == data.stack_parm
+ && MEM_P (data.entry_parm)
+ && int_size_in_bytes (data.passed_type))
+ data.stack_parm = NULL_RTX;
}
if (!POINTER_BOUNDS_TYPE_P (data.passed_type))
{