aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-02-17 18:32:45 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-02-17 18:32:45 +0000
commit57782ad852862c891585dbafea03ef854790e89b (patch)
tree85a8a16852397c2880c3b5467fc1063168a77fb7 /gcc/config
parent3977a4a1eec95645a03f78d85ed1f118cc7cfcbd (diff)
downloadgcc-57782ad852862c891585dbafea03ef854790e89b.zip
gcc-57782ad852862c891585dbafea03ef854790e89b.tar.gz
gcc-57782ad852862c891585dbafea03ef854790e89b.tar.bz2
re PR c++/11326 (C++ IA64 ABI: 3.1.4: sometimes pointer to temporary return value is implicit first parameter preceding "this")
PR c++/11326 * c-common.c (flag_abi_version): Remove. * c-common.h (flag_abi_version): Likewise. * c-opts.c (c_common_handle_option): Remove OPT_fabi_version case. * c.opt (fabi-version): Remove. * calls.c (expand_call): Always pass a function type to struct_value_rtx. Use convert_memory_address. * common.opt (fabi-version): Add it. * flags.h (flag_abi_version): Likewise. (abi_version_at_least): New macro. * opts.c (common_handle_option): Add OPT_fabi_version. * toplev.c (flag_abi_version): Define it. * config/ia64/ia64.c (ia64_struct_retval_addr_is_first_parm_p): New function. (ia64_output_mi_thunk): Use it. (ia64_struct_value_rtx): Likewise. PR c++/11326 * cp-tree.h (abi_version_at_least): Remove. * mangle.c: Include flags.h. PR c++/11326 * g++.dg/abi/structret1.C: New test. From-SVN: r77968
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/ia64/ia64.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 8dcee21..ffbb349 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -8802,6 +8802,27 @@ ia64_rwreloc_section_type_flags (tree decl, const char *name, int reloc)
return default_section_type_flags_1 (decl, name, reloc, true);
}
+/* Returns true if FNTYPE (a FUNCTION_TYPE or a METHOD_TYPE) returns a
+ structure type and that the address of that type should be passed
+ in out0, rather than in r8. */
+
+static bool
+ia64_struct_retval_addr_is_first_parm_p (tree fntype)
+{
+ tree ret_type = TREE_TYPE (fntype);
+
+ /* The Itanium C++ ABI requires that out0, rather than r8, be used
+ as the structure return address parameter, if the return value
+ type has a non-trivial copy constructor or destructor. It is not
+ clear if this same convention should be used for other
+ programming languages. Until G++ 3.4, we incorrectly used r8 for
+ these return values. */
+ return (abi_version_at_least (2)
+ && ret_type
+ && TYPE_MODE (ret_type) == BLKmode
+ && TREE_ADDRESSABLE (ret_type)
+ && strcmp (lang_hooks.name, "GNU C++") == 0);
+}
/* Output the assembler code for a thunk function. THUNK_DECL is the
declaration for the thunk function itself, FUNCTION is the decl for
@@ -8815,6 +8836,8 @@ ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
tree function)
{
rtx this, insn, funexp;
+ unsigned int this_parmno;
+ unsigned int this_regno;
reload_completed = 1;
epilogue_completed = 1;
@@ -8828,16 +8851,23 @@ ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
current_frame_info.n_input_regs = 1;
current_frame_info.need_regstk = (TARGET_REG_NAMES != 0);
- if (!TARGET_REG_NAMES)
- reg_names[IN_REG (0)] = ia64_reg_numbers[0];
-
/* Mark the end of the (empty) prologue. */
emit_note (NOTE_INSN_PROLOGUE_END);
- this = gen_rtx_REG (Pmode, IN_REG (0));
+ /* Figure out whether "this" will be the first parameter (the
+ typical case) or the second parameter (as happens when the
+ virtual function returns certain class objects). */
+ this_parmno
+ = (ia64_struct_retval_addr_is_first_parm_p (TREE_TYPE (thunk))
+ ? 1 : 0);
+ this_regno = IN_REG (this_parmno);
+ if (!TARGET_REG_NAMES)
+ reg_names[this_regno] = ia64_reg_numbers[this_parmno];
+
+ this = gen_rtx_REG (Pmode, this_regno);
if (TARGET_ILP32)
{
- rtx tmp = gen_rtx_REG (ptr_mode, IN_REG (0));
+ rtx tmp = gen_rtx_REG (ptr_mode, this_regno);
REG_POINTER (tmp) = 1;
if (delta && CONST_OK_FOR_I (delta))
{
@@ -8945,9 +8975,11 @@ ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* Worker function for TARGET_STRUCT_VALUE_RTX. */
static rtx
-ia64_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED,
+ia64_struct_value_rtx (tree fntype,
int incoming ATTRIBUTE_UNUSED)
{
+ if (ia64_struct_retval_addr_is_first_parm_p (fntype))
+ return NULL_RTX;
return gen_rtx_REG (Pmode, GR_REG (8));
}