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:
parent
459b4d1592
commit
603eaec49a
9 changed files with 123 additions and 7 deletions
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
29
gcc/testsuite/g++.dg/abi/mangle-regparm.C
Normal file
29
gcc/testsuite/g++.dg/abi/mangle-regparm.C
Normal 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);
|
||||
}
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Reference in a new issue