aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/c-common.c17
-rw-r--r--gcc/c-common.h15
-rw-r--r--gcc/c-opts.c4
-rw-r--r--gcc/c.opt3
-rw-r--r--gcc/calls.c14
-rw-r--r--gcc/common.opt3
-rw-r--r--gcc/config/ia64/ia64.c44
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/mangle.c1
-rw-r--r--gcc/flags.h21
-rw-r--r--gcc/opts.c4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/abi/structret1.C31
-rw-r--r--gcc/toplev.c17
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;
diff --git a/gcc/c.opt b/gcc/c.opt
index 4856fc5..2a2ff85 100644
--- a/gcc/c.opt
+++ b/gcc/c.opt
@@ -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
diff --git a/gcc/opts.c b/gcc/opts.c
index d54d1b4..45acba3 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -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;