Jason Merrill <ja...@redhat.com> writes: > On 12/18/19 1:24 PM, Richard Sandiford wrote: >> The SVE port needs to maintain a different type identity for >> GNU vectors and "SVE vectors" even during LTO, since the types >> use different ABIs. The easiest way of doing that seemed to be >> to use type attributes. However, these type attributes shouldn't >> be user-facing; they're just a convenient way of representing the >> types internally in GCC. >> >> There are already several internal-only attributes, such as "fn spec" >> and "omp declare simd". They're distinguished from normal user-facing >> attributes by having a space in their name, which means that it isn't >> possible to write them directly in C or C++. >> >> Taking the same approach mostly works well for SVE. The only snag >> I've hit so far is that the new attribute needs to (and only exists to) >> affect type identity. This means that it would normally get included >> in mangled names, to distinguish it from types without the attribute. >> >> However, the SVE ABI specifies a separate mangling for SVE vector types, >> rather than using an attribute mangling + a normal vector mangling. >> So we need some way of suppressing the attribute mangling for this case. >> >> There are currently no other target-independent or target-specific >> internal-only attributes that affect type identity, so this patch goes >> for the simplest fix of skipping mangling for attributes whose names >> contain a space. Other options I thought about were: >> >> (1) Also make sure that targetm.mangled_type returns nonnull. >> >> (2) Check directly for the target-specific name. >> >> (3) Add a new target hook. >> >> (4) Add new information to attribute_spec. This would be very invasive >> at this stage, but maybe we should consider replacing all the boolean >> fields with flags? That should make the tables slightly easier to >> read and would make adding new flags much simpler in future. >> >> What do you think? Do any of these sound OK, or is there a better >> way of doing it? >> >> Tested on aarch64-linux-gnu and x86_64-linux-gnu. >> >> Thanks, >> Richard >> >> >> 2019-12-18 Richard Sandiford <richard.sandif...@arm.com> >> >> gcc/cp/ >> * mangle.c (write_CV_qualifiers_for_type): Don't mangle attributes >> that contain a space. > > This approach works for me. Though that condition is getting large > enough that I might break it out into a separate function.
OK, here's a version with that change. I also expanded the comment slightly. Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install? Thanks, Richard 2019-12-27 Richard Sandiford <richard.sandif...@arm.com> gcc/cp/ * mangle.c (mangle_type_attribute_p): New function, split out from... (write_CV_qualifiers_for_type): ...here. Don't mangle attributes that contain a space. Index: gcc/cp/mangle.c =================================================================== --- gcc/cp/mangle.c 2019-12-27 15:59:54.000000000 +0000 +++ gcc/cp/mangle.c 2019-12-27 15:59:55.236935396 +0000 @@ -2348,6 +2348,34 @@ attr_strcmp (const void *p1, const void return strcmp (as1->name, as2->name); } +/* Return true if we should mangle a type attribute with name NAME. */ + +static bool +mangle_type_attribute_p (tree name) +{ + const attribute_spec *as = lookup_attribute_spec (name); + if (!as || !as->affects_type_identity) + return false; + + /* Skip internal-only attributes, which are distinguished from others + by having a space. At present, all internal-only attributes that + affect type identity are target-specific and are handled by + targetm.mangle_type instead. + + Another reason to do this is that a space isn't a valid identifier + character for most file formats. */ + if (strchr (IDENTIFIER_POINTER (name), ' ')) + return false; + + if (is_attribute_p ("transaction_safe", name)) + return false; + + if (is_attribute_p ("abi_tag", name)) + return false; + + return true; +} + /* Non-terminal <CV-qualifiers> for type nodes. Returns the number of CV-qualifiers written for TYPE. @@ -2373,14 +2401,8 @@ write_CV_qualifiers_for_type (const tree { 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 ("transaction_safe", name) - && !is_attribute_p ("abi_tag", name)) - vec.safe_push (a); - } + if (mangle_type_attribute_p (get_attribute_name (a))) + vec.safe_push (a); if (abi_warn_or_compat_version_crosses (10) && !vec.is_empty ()) G.need_abi_warning = true; if (abi_version_at_least (10))