diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-02-17 18:32:45 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-02-17 18:32:45 +0000 |
commit | 57782ad852862c891585dbafea03ef854790e89b (patch) | |
tree | 85a8a16852397c2880c3b5467fc1063168a77fb7 /gcc/config | |
parent | 3977a4a1eec95645a03f78d85ed1f118cc7cfcbd (diff) | |
download | gcc-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.c | 44 |
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)); } |