https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83300

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|ASSIGNED                    |NEW
           Assignee|jakub at gcc dot gnu.org           |unassigned at gcc dot 
gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
So, the problem is that on that testcase *decl_p is UNDERLYING_TYPE, and
build_type_attribute_variant (but cp_build_type_attribute_variant too, as it
calls it) calls layout_type on it and that ICEs, because it is a FE specific
type which it doesn't know what to do.
So, I bet we could use build_type_attribute_variant only if (!dependent_type_p
(*decl_p)).  The question is what to do with the dependent types, can we modify
them in place always, or shall we create build_variant_type_copy, or do we need
to do some hashing like e.g. build_cplus_array_type does?

This passes both tests, but I'm afraid our testsuite coverage of dependent
types with late attributes on them is very limited.

2017-12-07  Jakub Jelinek  <ja...@redhat.com>

        PR c++/83300
        * decl2.c (save_template_attributes): Add flags argument, if
        not ATTR_FLAG_TYPE_IN_PLACE, *decl_p is a type and we want to
        modify TYPE_ATTRIBUTES, add them on type attribute variant.

        * g++.dg/ext/vector33.C: New test.

--- gcc/cp/decl2.c.jj   2017-12-06 23:48:08.205147975 +0100
+++ gcc/cp/decl2.c      2017-12-07 09:39:18.539996630 +0100
@@ -1244,7 +1244,7 @@ splice_template_attributes (tree *attr_p
    DECL_P.  */

 static void
-save_template_attributes (tree *attr_p, tree *decl_p)
+save_template_attributes (tree *attr_p, tree *decl_p, int flags)
 {
   tree *q;

@@ -1265,7 +1265,20 @@ save_template_attributes (tree *attr_p,
   /* Merge the late attributes at the beginning with the attribute
      list.  */
   late_attrs = merge_attributes (late_attrs, *q);
-  *q = late_attrs;
+  if (*q != late_attrs
+      && !DECL_P (*decl_p)
+      && !(flags & ATTR_FLAG_TYPE_IN_PLACE))
+    {
+      if (!dependent_type_p (*decl_p))
+       *decl_p = cp_build_type_attribute_variant (*decl_p, late_attrs);
+      else
+       {
+         *decl_p = build_variant_type_copy (*decl_p);
+         TYPE_ATTRIBUTES (*decl_p) = late_attrs;
+       }
+    }
+  else
+    *q = late_attrs;

   if (!DECL_P (*decl_p) && *decl_p == TYPE_MAIN_VARIANT (*decl_p))
     {
@@ -1466,7 +1479,7 @@ cplus_decl_attributes (tree *decl, tree
       if (check_for_bare_parameter_packs (attributes))
        return;

-      save_template_attributes (&attributes, decl);
+      save_template_attributes (&attributes, decl, flags);
     }

   cp_check_const_attributes (attributes);
--- gcc/testsuite/g++.dg/ext/vector33.C.jj      2017-12-07 09:10:24.227635836
+0100
+++ gcc/testsuite/g++.dg/ext/vector33.C 2017-12-07 09:10:24.227635836 +0100
@@ -0,0 +1,10 @@
+// PR c++/83300
+// { dg-do compile { target c++11 } }
+
+template<int N>
+using T = int __attribute__((vector_size (sizeof(int) * N)));
+
+void
+f (T<4>)
+{
+}

Reply via email to