This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ RFC PATCH] Fix ICE with late attributes in templates (PR c++/83300)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 7 Dec 2017 17:45:46 +0100
- Subject: [C++ RFC PATCH] Fix ICE with late attributes in templates (PR c++/83300)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
save_template_attributes ignored flags, when ATTR_FLAG_TYPE_IN_PLACE
wasn't set on a type, it would happily attach the attributes to some
existing type (in this case to integer_type_node).
My first approach was to just call build_type_attribute_variant, but
that ICEs on g++.dg/cpp0x/alias-decl-59.C, because there *decl_p is
UNDERLYING_TYPE, which the generic type_hash_canon
build_type_attribute_variant calls doesn't like.
This patch just creates a new variant type if *decl_p is dependent,
it passes bootstrap/regtest, but I'm not really sure if we need any
kind of FE type hashing for such types (when pt.c will handle it with
!processing_template_decl it will be built using
build_type_attribute_variant and afterwards we'll have the types hashed).
So, is this enough, or do we need to do something else (and what)?
2017-12-07 Jakub Jelinek <jakub@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>)
+{
+}
Jakub