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 | |
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
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/c-common.c | 17 | ||||
-rw-r--r-- | gcc/c-common.h | 15 | ||||
-rw-r--r-- | gcc/c-opts.c | 4 | ||||
-rw-r--r-- | gcc/c.opt | 3 | ||||
-rw-r--r-- | gcc/calls.c | 14 | ||||
-rw-r--r-- | gcc/common.opt | 3 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.c | 44 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 6 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 1 | ||||
-rw-r--r-- | gcc/flags.h | 21 | ||||
-rw-r--r-- | gcc/opts.c | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/abi/structret1.C | 31 | ||||
-rw-r--r-- | gcc/toplev.c | 17 |
16 files changed, 154 insertions, 56 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 04f0f75..c099df6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2004-02-17 Mark Mitchell <mark@codesourcery.com> + + 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. + 2004-02-17 Kazu Hirata <kazu@cs.umass.edu> * config/h8300/h8300.c (h8300_emit_stack_adjustment): diff --git a/gcc/c-common.c b/gcc/c-common.c index 184f26e..63ce3c7 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -599,23 +599,6 @@ int flag_permissive; int flag_enforce_eh_specs = 1; -/* The version of the C++ ABI in use. The following values are - allowed: - - 0: The version of the ABI believed most conformant with the - C++ ABI specification. This ABI may change as bugs are - discovered and fixed. Therefore, 0 will not necessarily - indicate the same ABI in different versions of G++. - - 1: The version of the ABI first used in G++ 3.2. - - 2: The version of the ABI first used in G++ 3.4. - - Additional positive integers will be assigned as new versions of - the ABI become the default version of the ABI. */ - -int flag_abi_version = 2; - /* Nonzero means warn about things that will change when compiling with an ABI-compliant compiler. */ diff --git a/gcc/c-common.h b/gcc/c-common.h index f409e7a..00d5d5c 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -760,21 +760,6 @@ extern int flag_permissive; extern int flag_enforce_eh_specs; -/* The version of the C++ ABI in use. The following values are - allowed: - - 0: The version of the ABI believed most conformant with the - C++ ABI specification. This ABI may change as bugs are - discovered and fixed. Therefore, 0 will not necessarily - indicate the same ABI in different versions of G++. - - 1: The version of the ABI first used in G++ 3.2. - - Additional positive integers will be assigned as new versions of - the ABI become the default version of the ABI. */ - -extern int flag_abi_version; - /* Nonzero means warn about things that will change when compiling with an ABI-compliant compiler. */ diff --git a/gcc/c-opts.c b/gcc/c-opts.c index 37d2ac4..a0d7382 100644 --- a/gcc/c-opts.c +++ b/gcc/c-opts.c @@ -692,10 +692,6 @@ c_common_handle_option (size_t scode, const char *arg, int value) warning ("switch \"%s\" is no longer supported", option->opt_text); break; - case OPT_fabi_version_: - flag_abi_version = value; - break; - case OPT_faccess_control: flag_access_control = value; break; @@ -411,9 +411,6 @@ d C ObjC C++ ObjC++ Joined ; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD? -fabi-version= -C++ ObjC++ Joined UInteger - faccess-control C++ ObjC++ Enforce class member access control semantics diff --git a/gcc/calls.c b/gcc/calls.c index d702ed0..c667575 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -2080,6 +2080,8 @@ expand_call (tree exp, rtx target, int ignore) /* Declaration of the function being called, or 0 if the function is computed (not known by name). */ tree fndecl = 0; + /* The type of the function being called. */ + tree fntype; rtx insn; int try_tail_call = 1; int try_tail_recursion = 1; @@ -2188,6 +2190,7 @@ expand_call (tree exp, rtx target, int ignore) fndecl = get_callee_fndecl (exp); if (fndecl) { + fntype = TREE_TYPE (fndecl); if (!flag_no_inline && fndecl != current_function_decl && DECL_INLINE (fndecl) @@ -2223,15 +2226,15 @@ expand_call (tree exp, rtx target, int ignore) attributes set in the type. */ else { + fntype = TREE_TYPE (TREE_TYPE (p)); if (ignore - && lookup_attribute ("warn_unused_result", - TYPE_ATTRIBUTES (TREE_TYPE (TREE_TYPE (p))))) + && lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (fntype))) warning ("ignoring return value of function " "declared with attribute warn_unused_result"); - flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p))); + flags |= flags_from_decl_or_type (fntype); } - struct_value = targetm.calls.struct_value_rtx (fndecl ? TREE_TYPE (fndecl) : 0, 0); + struct_value = targetm.calls.struct_value_rtx (fntype, 0); /* Warn if this value is an aggregate type, regardless of which calling convention we are using for it. */ @@ -2385,7 +2388,8 @@ expand_call (tree exp, rtx target, int ignore) || (ACCUMULATE_OUTGOING_ARGS && stack_arg_under_construction && structure_value_addr == virtual_outgoing_args_rtx) - ? copy_addr_to_reg (structure_value_addr) + ? copy_addr_to_reg (convert_memory_address + (Pmode, structure_value_addr)) : structure_value_addr); actparms diff --git a/gcc/common.opt b/gcc/common.opt index 4c08b97..8598d8c 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -179,6 +179,9 @@ Common fPIE Common +fabi-version= +Common Joined UInteger + falign-functions Common Align the start of functions 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)); } diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6c5e957..48edcfd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-02-17 Mark Mitchell <mark@codesourcery.com> + + PR c++/11326 + * cp-tree.h (abi_version_at_least): Remove. + * mangle.c: Include flags.h. + 2004-02-15 Mark Mitchell <mark@codesourcery.com> PR c++/13971 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 0097c42..36acc5a 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -213,12 +213,6 @@ struct diagnostic_context; #endif -/* Returns TRUE if generated code should match ABI version N or - greater is in use. */ - -#define abi_version_at_least(N) \ - (flag_abi_version == 0 || flag_abi_version >= (N)) - /* Language-dependent contents of an identifier. */ diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 70b022b..a41c141 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -58,6 +58,7 @@ #include "obstack.h" #include "toplev.h" #include "varray.h" +#include "flags.h" /* Debugging support. */ diff --git a/gcc/flags.h b/gcc/flags.h index 1ca9d98..626993f 100644 --- a/gcc/flags.h +++ b/gcc/flags.h @@ -731,6 +731,27 @@ extern int flag_var_tracking; extern const char *flag_random_seed; +/* The version of the C++ ABI in use. The following values are + allowed: + + 0: The version of the ABI believed most conformant with the + C++ ABI specification. This ABI may change as bugs are + discovered and fixed. Therefore, 0 will not necessarily + indicate the same ABI in different versions of G++. + + 1: The version of the ABI first used in G++ 3.2. + + Additional positive integers will be assigned as new versions of + the ABI become the default version of the ABI. */ + +extern int flag_abi_version; + +/* Returns TRUE if generated code should match ABI version N or + greater is in use. */ + +#define abi_version_at_least(N) \ + (flag_abi_version == 0 || flag_abi_version >= (N)) + /* True if the given mode has a NaN representation and the treatment of NaN operands is important. Certain optimizations, such as folding x * 0 into x, are not correct for NaN operands, and are normally @@ -833,6 +833,10 @@ common_handle_option (size_t scode, const char *arg, flag_pie = value + value; break; + case OPT_fabi_version_: + flag_abi_version = value; + break; + case OPT_falign_functions: align_functions = !value; break; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7529302..a49e599 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-02-17 Mark Mitchell <mark@codesourcery.com> + + PR c++/11326 + * g++.dg/abi/structret1.C: New test. + 2004-02-17 Jakub Jelinek <jakub@redhat.com> * gcc.dg/i386-cpuid.h (bit_CMOV): Define. diff --git a/gcc/testsuite/g++.dg/abi/structret1.C b/gcc/testsuite/g++.dg/abi/structret1.C new file mode 100644 index 0000000..e9d4fd0 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/structret1.C @@ -0,0 +1,31 @@ +// { dg-do run { target ia64-*-* } } +// { dg-options "-fabi-version=0" } + +extern "C" void abort (); + +struct ConstructedObject { + ConstructedObject() {}; + ~ConstructedObject() {}; + ConstructedObject(const ConstructedObject &from) {}; +}; + +struct FrameworkObject { + ConstructedObject action(); +}; + +ConstructedObject FrameworkObject::action() { + void *r32, *r33; + + asm("mov %0 = r32\nmov %1 = r33" : "=r"(r32), "=r"(r33) : ); + if (this != r33) { + abort (); + } +} + +int main() +{ + FrameworkObject slawa; + slawa.action(); + return 0; +} + diff --git a/gcc/toplev.c b/gcc/toplev.c index c470cf0..7473ead 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1016,6 +1016,23 @@ int flag_evaluation_order = 0; /* Add or remove a leading underscore from user symbols. */ int flag_leading_underscore = -1; +/* The version of the C++ ABI in use. The following values are + allowed: + + 0: The version of the ABI believed most conformant with the + C++ ABI specification. This ABI may change as bugs are + discovered and fixed. Therefore, 0 will not necessarily + indicate the same ABI in different versions of G++. + + 1: The version of the ABI first used in G++ 3.2. + + 2: The version of the ABI first used in G++ 3.4. + + Additional positive integers will be assigned as new versions of + the ABI become the default version of the ABI. */ + +int flag_abi_version = 2; + /* The user symbol prefix after having resolved same. */ const char *user_label_prefix; |