aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDouglas Gregor <doug.gregor@gmail.com>2008-02-05 13:29:43 +0000
committerDoug Gregor <dgregor@gcc.gnu.org>2008-02-05 13:29:43 +0000
commit1db54f4e49894663db378fe462590f7a91ae75ec (patch)
tree6e7ba93340a32ec6b5dfb7440327efee8a37079c /gcc
parent0f5098aef3678a7b6966a8bcabd7a4d05020fd23 (diff)
downloadgcc-1db54f4e49894663db378fe462590f7a91ae75ec.zip
gcc-1db54f4e49894663db378fe462590f7a91ae75ec.tar.gz
gcc-1db54f4e49894663db378fe462590f7a91ae75ec.tar.bz2
re PR c++/35074 (ICE with attribute "aligned" for template classes)
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. From-SVN: r132120
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/decl2.c22
-rw-r--r--gcc/testsuite/g++.dg/ext/attrib30.C8
3 files changed, 36 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0cd642b..5ea0490 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+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-04 Richard Guenther <rguenther@suse.de>
PR java/35035
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 3b20586..d2d81fe 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1068,6 +1068,7 @@ save_template_attributes (tree *attr_p, tree *decl_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, tree *decl_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. */
diff --git a/gcc/testsuite/g++.dg/ext/attrib30.C b/gcc/testsuite/g++.dg/ext/attrib30.C
new file mode 100644
index 0000000..fd2826a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attrib30.C
@@ -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 {}