re PR c++/44282 (fastcall is not mangled at all)

PR c++/44282
gcc/cp/
	* mangle.c (attr_strcmp): New.
	(write_CV_qualifiers_for_type): Also write out attributes that
	affect type identity.
	(write_type): Strip all attributes after writing qualifiers.
libiberty/
	* cp-demangle.c (cplus_demangle_type): Handle arguments to vendor
	extended qualifier.

From-SVN: r224007
This commit is contained in:
Jason Merrill 2015-06-01 22:28:19 -04:00 committed by Jason Merrill
parent 459b4d1592
commit 603eaec49a
9 changed files with 123 additions and 7 deletions

View File

@ -894,7 +894,7 @@ c_common_post_options (const char **pfilename)
/* Change flag_abi_version to be the actual current ABI level for the
benefit of c_cpp_builtins. */
if (flag_abi_version == 0)
flag_abi_version = 8;
flag_abi_version = 9;
/* Set C++ standard to C++98 if not specified on the command line. */
if (c_dialect_cxx () && cxx_dialect == cxx_unset)

View File

@ -836,8 +836,11 @@ Driver Undocumented
;
; 8: The version of the ABI that corrects the substitution behavior of
; function types with function-cv-qualifiers.
; First selectable in G++ 4.9 and default in G++ 5
; (set in c_common_post_options).
; First selectable in G++ 4.9 and default in G++ 5.
;
; 9: The version of the ABI that mangles attributes that affect type
; identity, such as ia32 calling convention attributes (stdcall, etc.)
; Default in G++ 6 (set in c_common_post_options).
;
; Additional positive integers will be assigned as new versions of
; the ABI become the default version of the ABI.

View File

@ -1,3 +1,11 @@
2015-06-01 Jason Merrill <jason@redhat.com>
PR c++/44282
* mangle.c (attr_strcmp): New.
(write_CV_qualifiers_for_type): Also write out attributes that
affect type identity.
(write_type): Strip all attributes after writing qualifiers.
2015-05-31 Jason Merrill <jason@redhat.com>
* constexpr.c (cxx_eval_indirect_ref): Try folding first.

View File

@ -75,6 +75,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-ref.h"
#include "cgraph.h"
#include "wide-int.h"
#include "attribs.h"
/* Debugging support. */
@ -1916,11 +1917,15 @@ write_type (tree type)
candidates. */
{
tree t = TYPE_MAIN_VARIANT (type);
if (TYPE_ATTRIBUTES (t) && !OVERLOAD_TYPE_P (t))
t = cp_build_type_attribute_variant (t, NULL_TREE);
gcc_assert (t != type);
if (TREE_CODE (t) == FUNCTION_TYPE
|| TREE_CODE (t) == METHOD_TYPE)
{
t = build_ref_qualified_type (t, type_memfn_rqual (type));
if (abi_version_at_least (8))
if (abi_version_at_least (8)
|| type == TYPE_MAIN_VARIANT (type))
/* Avoid adding the unqualified function type as a substitution. */
write_function_type (t);
else
@ -2168,6 +2173,20 @@ write_type (tree type)
add_substitution (type);
}
/* qsort callback for sorting a vector of attribute entries. */
static int
attr_strcmp (const void *p1, const void *p2)
{
tree a1 = *(const tree*)p1;
tree a2 = *(const tree*)p2;
const attribute_spec *as1 = lookup_attribute_spec (get_attribute_name (a1));
const attribute_spec *as2 = lookup_attribute_spec (get_attribute_name (a2));
return strcmp (as1->name, as2->name);
}
/* Non-terminal <CV-qualifiers> for type nodes. Returns the number of
CV-qualifiers written for TYPE.
@ -2182,9 +2201,55 @@ write_CV_qualifiers_for_type (const tree type)
"In cases where multiple order-insensitive qualifiers are
present, they should be ordered 'K' (closest to the base type),
'V', 'r', and 'U' (farthest from the base type) ..."
'V', 'r', and 'U' (farthest from the base type) ..." */
Note that we do not use cp_type_quals below; given "const
/* Mangle attributes that affect type identity as extended qualifiers.
We mangle them onto the obstack, then copy the result into a string
vector and back up the obstack. Once we've handled all of them we
sort them and write them out in order.
We don't do this with classes and enums because their attributes
are part of their definitions, not something added on. */
if (abi_version_at_least (9) && !OVERLOAD_TYPE_P (type))
{
auto_vec<tree> vec;
for (tree a = TYPE_ATTRIBUTES (type); a; a = TREE_CHAIN (a))
{
tree name = get_attribute_name (a);
const attribute_spec *as = lookup_attribute_spec (name);
if (as && as->affects_type_identity
&& !is_attribute_p ("abi_tag", name))
vec.safe_push (a);
}
vec.qsort (attr_strcmp);
while (!vec.is_empty())
{
tree a = vec.pop();
const attribute_spec *as
= lookup_attribute_spec (get_attribute_name (a));
write_char ('U');
write_unsigned_number (strlen (as->name));
write_string (as->name);
if (TREE_VALUE (a))
{
write_char ('I');
for (tree args = TREE_VALUE (a); args;
args = TREE_CHAIN (args))
{
tree arg = TREE_VALUE (args);
write_template_arg (arg);
}
write_char ('E');
}
++num_qualifiers;
}
}
/* Note that we do not use cp_type_quals below; given "const
int[3]", the "const" is emitted with the "int", not with the
array. */
cp_cv_quals quals = TYPE_QUALS (type);

View File

@ -1,6 +1,6 @@
// This testcase will need to be kept in sync with c_common_post_options.
// { dg-options "-fabi-version=0" }
#if __GXX_ABI_VERSION != 1008
#if __GXX_ABI_VERSION != 1009
#error "Incorrect value of __GXX_ABI_VERSION"
#endif

View File

@ -0,0 +1,29 @@
// { dg-do run { target i?86-*-* } }
// { dg-final { scan-assembler "_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_" } }
typedef __SIZE_TYPE__ size_t;
template <typename F, typename T>
void IndirectExternCall(F f, T t1, T t2) {
typedef F (*WrapF)(F);
f (t1, t2);
}
__attribute__((regparm(3), stdcall))
void regparm_func (int i, int j)
{
if (i != 24 || j != 42)
__builtin_abort();
}
void normal_func (int i, int j)
{
if (i != 24 || j != 42)
__builtin_abort();
}
int main()
{
IndirectExternCall (regparm_func, 24, 42);
IndirectExternCall (normal_func, 24, 42);
}

View File

@ -1,3 +1,8 @@
2015-06-01 Jason Merrill <jason@redhat.com>
* cp-demangle.c (cplus_demangle_type): Handle arguments to vendor
extended qualifier.
2015-05-22 Yunlian Jiang <yunlian@google.com>
* configure.ac: Add AC_GNU_SOURCE.

View File

@ -2470,6 +2470,9 @@ cplus_demangle_type (struct d_info *di)
case 'U':
d_advance (di, 1);
ret = d_source_name (di);
if (d_peek_char (di) == 'I')
ret = d_make_comp (di, DEMANGLE_COMPONENT_TEMPLATE, ret,
d_template_args (di));
ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
cplus_demangle_type (di), ret);
break;

View File

@ -4356,3 +4356,6 @@ _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
--format=gnu-v3
_Z1fSsB3fooS_
f(std::string[abi:foo], std::string[abi:foo])
--format=gnu-v3
_Z18IndirectExternCallIPU7stdcallU7regparmILi3EEFviiEiEvT_T0_S3_
void IndirectExternCall<void ( regparm<3> stdcall*)(int, int), int>(void ( regparm<3> stdcall*)(int, int), int, void ( regparm<3> stdcall*)(int, int))