This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ PATCH] Class template attributes and canonical types (PR c++/35074)


On Feb 4, 2008 10:34 PM, Jason Merrill <jason@redhat.com> wrote:
> > +       if (TYPE_ATTRIBUTES (variant) == old_attrs)
>
> This should always be true; we ignore attributes applied to a class
> other than on the definition.

... and only a class can be a template. Great, that makes things simpler.

> > +         TYPE_ATTRIBUTES (variant) = TYPE_ATTRIBUTES (*decl_p);
>
> And this a no-op, since I added the new attributes to the end of the
> chain.  But it's probably better to add them to the beginning, like
> decl_attributes does.  Want to make that change?

It isn't a no-op because the variant may not have had any attributes
to start with. But, I'll put the new attributes at the beginning of
the list. Here's the patch as committed.

  - Doug

2008-02-05  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/35074
	* decl2.c (save_template_attributes): When we're modifying the
	TYPE_MAIN_VARIANT to add new attributes, be sure to also modify
	all of the other variants to add those same attributes. Otherwise,
	the main variant will be inconsistent with those other variants.
	
2008-02-05  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/35074
	* g++.dg/ext/attrib30.C: New.

Index: cp/decl2.c
===================================================================
--- cp/decl2.c	(revision 132096)
+++ cp/decl2.c	(working copy)
@@ -1068,6 +1068,7 @@ save_template_attributes (tree *attr_p,
 {
   tree late_attrs = splice_template_attributes (attr_p, *decl_p);
   tree *q;
+  tree old_attrs = NULL_TREE;

   if (!late_attrs)
     return;
@@ -1090,9 +1091,26 @@ save_template_attributes (tree *attr_p,
   else
     q = &TYPE_ATTRIBUTES (*decl_p);

-  if (*q)
-    q = &TREE_CHAIN (tree_last (*q));
+  old_attrs = *q;
+
+  /* Place the late attributes at the beginning of the attribute
+     list.  */
+  TREE_CHAIN (tree_last (late_attrs)) = *q;
   *q = late_attrs;
+
+  if (!DECL_P (*decl_p) && *decl_p == TYPE_MAIN_VARIANT (*decl_p))
+    {
+      /* We've added new attributes directly to the main variant, so
+	 now we need to update all of the other variants to include
+	 these new attributes.  */
+      tree variant;
+      for (variant = TYPE_NEXT_VARIANT (*decl_p); variant;
+	   variant = TYPE_NEXT_VARIANT (variant))
+	{
+	  gcc_assert (TYPE_ATTRIBUTES (variant) == old_attrs);
+	  TYPE_ATTRIBUTES (variant) = TYPE_ATTRIBUTES (*decl_p);
+	}
+    }
 }

 /* Like decl_attributes, but handle C++ complexity.  */
Index: testsuite/g++.dg/ext/attrib30.C
===================================================================
--- testsuite/g++.dg/ext/attrib30.C	(revision 0)
+++ testsuite/g++.dg/ext/attrib30.C	(revision 0)
@@ -0,0 +1,8 @@
+// { dg-do compile }
+// PR c++/35074
+template<typename T> struct A
+{
+  void foo() const;
+} __attribute((aligned(4)));
+
+template<typename T> void A<T>::foo() const {}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]