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))

Reply via email to