diff options
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 19 |
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)) { |