Commit 603eaec4 by Jason Merrill Committed by Jason Merrill

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
parent 459b4d15
...@@ -894,7 +894,7 @@ c_common_post_options (const char **pfilename) ...@@ -894,7 +894,7 @@ c_common_post_options (const char **pfilename)
/* Change flag_abi_version to be the actual current ABI level for the /* Change flag_abi_version to be the actual current ABI level for the
benefit of c_cpp_builtins. */ benefit of c_cpp_builtins. */
if (flag_abi_version == 0) 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. */ /* Set C++ standard to C++98 if not specified on the command line. */
if (c_dialect_cxx () && cxx_dialect == cxx_unset) if (c_dialect_cxx () && cxx_dialect == cxx_unset)
......
...@@ -836,8 +836,11 @@ Driver Undocumented ...@@ -836,8 +836,11 @@ Driver Undocumented
; ;
; 8: The version of the ABI that corrects the substitution behavior of ; 8: The version of the ABI that corrects the substitution behavior of
; function types with function-cv-qualifiers. ; function types with function-cv-qualifiers.
; First selectable in G++ 4.9 and default in G++ 5 ; First selectable in G++ 4.9 and default in G++ 5.
; (set in c_common_post_options). ;
; 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 ; Additional positive integers will be assigned as new versions of
; the ABI become the default version of the ABI. ; the ABI become the default version of the ABI.
......
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> 2015-05-31 Jason Merrill <jason@redhat.com>
* constexpr.c (cxx_eval_indirect_ref): Try folding first. * constexpr.c (cxx_eval_indirect_ref): Try folding first.
......
...@@ -75,6 +75,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -75,6 +75,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-ref.h" #include "ipa-ref.h"
#include "cgraph.h" #include "cgraph.h"
#include "wide-int.h" #include "wide-int.h"
#include "attribs.h"
/* Debugging support. */ /* Debugging support. */
...@@ -1916,11 +1917,15 @@ write_type (tree type) ...@@ -1916,11 +1917,15 @@ write_type (tree type)
candidates. */ candidates. */
{ {
tree t = TYPE_MAIN_VARIANT (type); 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 if (TREE_CODE (t) == FUNCTION_TYPE
|| TREE_CODE (t) == METHOD_TYPE) || TREE_CODE (t) == METHOD_TYPE)
{ {
t = build_ref_qualified_type (t, type_memfn_rqual (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. */ /* Avoid adding the unqualified function type as a substitution. */
write_function_type (t); write_function_type (t);
else else
...@@ -2168,6 +2173,20 @@ write_type (tree type) ...@@ -2168,6 +2173,20 @@ write_type (tree type)
add_substitution (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 /* Non-terminal <CV-qualifiers> for type nodes. Returns the number of
CV-qualifiers written for TYPE. CV-qualifiers written for TYPE.
...@@ -2182,9 +2201,55 @@ write_CV_qualifiers_for_type (const tree type) ...@@ -2182,9 +2201,55 @@ write_CV_qualifiers_for_type (const tree type)
"In cases where multiple order-insensitive qualifiers are "In cases where multiple order-insensitive qualifiers are
present, they should be ordered 'K' (closest to the base type), 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) ..." */
/* 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 /* Note that we do not use cp_type_quals below; given "const
int[3]", the "const" is emitted with the "int", not with the int[3]", the "const" is emitted with the "int", not with the
array. */ array. */
cp_cv_quals quals = TYPE_QUALS (type); cp_cv_quals quals = TYPE_QUALS (type);
......
// This testcase will need to be kept in sync with c_common_post_options. // This testcase will need to be kept in sync with c_common_post_options.
// { dg-options "-fabi-version=0" } // { dg-options "-fabi-version=0" }
#if __GXX_ABI_VERSION != 1008 #if __GXX_ABI_VERSION != 1009
#error "Incorrect value of __GXX_ABI_VERSION" #error "Incorrect value of __GXX_ABI_VERSION"
#endif #endif
// { 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);
}
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> 2015-05-22 Yunlian Jiang <yunlian@google.com>
* configure.ac: Add AC_GNU_SOURCE. * configure.ac: Add AC_GNU_SOURCE.
......
...@@ -2470,6 +2470,9 @@ cplus_demangle_type (struct d_info *di) ...@@ -2470,6 +2470,9 @@ cplus_demangle_type (struct d_info *di)
case 'U': case 'U':
d_advance (di, 1); d_advance (di, 1);
ret = d_source_name (di); 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, ret = d_make_comp (di, DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL,
cplus_demangle_type (di), ret); cplus_demangle_type (di), ret);
break; break;
......
...@@ -4356,3 +4356,6 @@ _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z ...@@ -4356,3 +4356,6 @@ _QueueNotification_QueueController__$4PPPPPPPM_A_INotice___Z
--format=gnu-v3 --format=gnu-v3
_Z1fSsB3fooS_ _Z1fSsB3fooS_
f(std::string[abi:foo], std::string[abi:foo]) 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))
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