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
This commit is contained in:
Mark Mitchell 2004-02-17 18:32:45 +00:00 committed by Mark Mitchell
parent 3977a4a1ee
commit 57782ad852
16 changed files with 154 additions and 56 deletions

View File

@ -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):

View File

@ -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. */

View File

@ -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. */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -179,6 +179,9 @@ Common
fPIE
Common
fabi-version=
Common Joined UInteger
falign-functions
Common
Align the start of functions

View File

@ -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));
}

View File

@ -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

View File

@ -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. */

View File

@ -58,6 +58,7 @@
#include "obstack.h"
#include "toplev.h"
#include "varray.h"
#include "flags.h"
/* Debugging support. */

View File

@ -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

View File

@ -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;

View File

@ -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.

View File

@ -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;
}

View File

@ -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;