Commit 57782ad8 by Mark Mitchell Committed by Mark Mitchell

re PR c++/11326 (C++ IA64 ABI: 3.1.4: sometimes pointer to temporary return…

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
parent 3977a4a1
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> 2004-02-17 Kazu Hirata <kazu@cs.umass.edu>
* config/h8300/h8300.c (h8300_emit_stack_adjustment): * config/h8300/h8300.c (h8300_emit_stack_adjustment):
......
...@@ -599,23 +599,6 @@ int flag_permissive; ...@@ -599,23 +599,6 @@ int flag_permissive;
int flag_enforce_eh_specs = 1; 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 /* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */ with an ABI-compliant compiler. */
......
...@@ -760,21 +760,6 @@ extern int flag_permissive; ...@@ -760,21 +760,6 @@ extern int flag_permissive;
extern int flag_enforce_eh_specs; 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 /* Nonzero means warn about things that will change when compiling
with an ABI-compliant compiler. */ with an ABI-compliant compiler. */
......
...@@ -692,10 +692,6 @@ c_common_handle_option (size_t scode, const char *arg, int value) ...@@ -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); warning ("switch \"%s\" is no longer supported", option->opt_text);
break; break;
case OPT_fabi_version_:
flag_abi_version = value;
break;
case OPT_faccess_control: case OPT_faccess_control:
flag_access_control = value; flag_access_control = value;
break; break;
......
...@@ -411,9 +411,6 @@ d ...@@ -411,9 +411,6 @@ d
C ObjC C++ ObjC++ Joined C ObjC C++ ObjC++ Joined
; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD? ; Documented in common.opt. FIXME - what about -dI, -dD, -dN and -dD?
fabi-version=
C++ ObjC++ Joined UInteger
faccess-control faccess-control
C++ ObjC++ C++ ObjC++
Enforce class member access control semantics Enforce class member access control semantics
......
...@@ -2080,6 +2080,8 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2080,6 +2080,8 @@ expand_call (tree exp, rtx target, int ignore)
/* Declaration of the function being called, /* Declaration of the function being called,
or 0 if the function is computed (not known by name). */ or 0 if the function is computed (not known by name). */
tree fndecl = 0; tree fndecl = 0;
/* The type of the function being called. */
tree fntype;
rtx insn; rtx insn;
int try_tail_call = 1; int try_tail_call = 1;
int try_tail_recursion = 1; int try_tail_recursion = 1;
...@@ -2188,6 +2190,7 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2188,6 +2190,7 @@ expand_call (tree exp, rtx target, int ignore)
fndecl = get_callee_fndecl (exp); fndecl = get_callee_fndecl (exp);
if (fndecl) if (fndecl)
{ {
fntype = TREE_TYPE (fndecl);
if (!flag_no_inline if (!flag_no_inline
&& fndecl != current_function_decl && fndecl != current_function_decl
&& DECL_INLINE (fndecl) && DECL_INLINE (fndecl)
...@@ -2223,15 +2226,15 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2223,15 +2226,15 @@ expand_call (tree exp, rtx target, int ignore)
attributes set in the type. */ attributes set in the type. */
else else
{ {
fntype = TREE_TYPE (TREE_TYPE (p));
if (ignore if (ignore
&& lookup_attribute ("warn_unused_result", && lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (fntype)))
TYPE_ATTRIBUTES (TREE_TYPE (TREE_TYPE (p)))))
warning ("ignoring return value of function " warning ("ignoring return value of function "
"declared with attribute warn_unused_result"); "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, /* Warn if this value is an aggregate type,
regardless of which calling convention we are using for it. */ regardless of which calling convention we are using for it. */
...@@ -2385,7 +2388,8 @@ expand_call (tree exp, rtx target, int ignore) ...@@ -2385,7 +2388,8 @@ expand_call (tree exp, rtx target, int ignore)
|| (ACCUMULATE_OUTGOING_ARGS || (ACCUMULATE_OUTGOING_ARGS
&& stack_arg_under_construction && stack_arg_under_construction
&& structure_value_addr == virtual_outgoing_args_rtx) && 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); : structure_value_addr);
actparms actparms
......
...@@ -179,6 +179,9 @@ Common ...@@ -179,6 +179,9 @@ Common
fPIE fPIE
Common Common
fabi-version=
Common Joined UInteger
falign-functions falign-functions
Common Common
Align the start of functions Align the start of functions
......
...@@ -8802,6 +8802,27 @@ ia64_rwreloc_section_type_flags (tree decl, const char *name, int reloc) ...@@ -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); 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 /* Output the assembler code for a thunk function. THUNK_DECL is the
declaration for the thunk function itself, FUNCTION is the decl for 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, ...@@ -8815,6 +8836,8 @@ ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
tree function) tree function)
{ {
rtx this, insn, funexp; rtx this, insn, funexp;
unsigned int this_parmno;
unsigned int this_regno;
reload_completed = 1; reload_completed = 1;
epilogue_completed = 1; epilogue_completed = 1;
...@@ -8828,16 +8851,23 @@ ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -8828,16 +8851,23 @@ ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
current_frame_info.n_input_regs = 1; current_frame_info.n_input_regs = 1;
current_frame_info.need_regstk = (TARGET_REG_NAMES != 0); 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. */ /* Mark the end of the (empty) prologue. */
emit_note (NOTE_INSN_PROLOGUE_END); 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) 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; REG_POINTER (tmp) = 1;
if (delta && CONST_OK_FOR_I (delta)) if (delta && CONST_OK_FOR_I (delta))
{ {
...@@ -8945,9 +8975,11 @@ ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, ...@@ -8945,9 +8975,11 @@ ia64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
/* Worker function for TARGET_STRUCT_VALUE_RTX. */ /* Worker function for TARGET_STRUCT_VALUE_RTX. */
static rtx static rtx
ia64_struct_value_rtx (tree fntype ATTRIBUTE_UNUSED, ia64_struct_value_rtx (tree fntype,
int incoming ATTRIBUTE_UNUSED) 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)); return gen_rtx_REG (Pmode, GR_REG (8));
} }
......
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> 2004-02-15 Mark Mitchell <mark@codesourcery.com>
PR c++/13971 PR c++/13971
......
...@@ -213,12 +213,6 @@ struct diagnostic_context; ...@@ -213,12 +213,6 @@ struct diagnostic_context;
#endif #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. */ /* Language-dependent contents of an identifier. */
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#include "obstack.h" #include "obstack.h"
#include "toplev.h" #include "toplev.h"
#include "varray.h" #include "varray.h"
#include "flags.h"
/* Debugging support. */ /* Debugging support. */
......
...@@ -731,6 +731,27 @@ extern int flag_var_tracking; ...@@ -731,6 +731,27 @@ extern int flag_var_tracking;
extern const char *flag_random_seed; 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 /* True if the given mode has a NaN representation and the treatment of
NaN operands is important. Certain optimizations, such as folding NaN operands is important. Certain optimizations, such as folding
x * 0 into x, are not correct for NaN operands, and are normally 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, ...@@ -833,6 +833,10 @@ common_handle_option (size_t scode, const char *arg,
flag_pie = value + value; flag_pie = value + value;
break; break;
case OPT_fabi_version_:
flag_abi_version = value;
break;
case OPT_falign_functions: case OPT_falign_functions:
align_functions = !value; align_functions = !value;
break; break;
......
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> 2004-02-17 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/i386-cpuid.h (bit_CMOV): Define. * gcc.dg/i386-cpuid.h (bit_CMOV): Define.
......
// { 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;
}
...@@ -1016,6 +1016,23 @@ int flag_evaluation_order = 0; ...@@ -1016,6 +1016,23 @@ int flag_evaluation_order = 0;
/* Add or remove a leading underscore from user symbols. */ /* Add or remove a leading underscore from user symbols. */
int flag_leading_underscore = -1; 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. */ /* The user symbol prefix after having resolved same. */
const char *user_label_prefix; const char *user_label_prefix;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment