From 1db54f4e49894663db378fe462590f7a91ae75ec Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 5 Feb 2008 13:29:43 +0000 Subject: [PATCH] re PR c++/35074 (ICE with attribute "aligned" for template classes) 2008-02-05 Douglas Gregor 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 PR c++/35074 * g++.dg/ext/attrib30.C: New. From-SVN: r132120 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/decl2.c | 22 ++++++++++++++++++++-- gcc/testsuite/g++.dg/ext/attrib30.C | 8 ++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/attrib30.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0cd642ba1e1..5ea0490684c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2008-02-05 Douglas Gregor + + 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 PR java/35035 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 3b20586457c..d2d81feae44 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 00000000000..fd2826a6029 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib30.C @@ -0,0 +1,8 @@ +// { dg-do compile } +// PR c++/35074 +template struct A +{ + void foo() const; +} __attribute((aligned(4))); + +template void A::foo() const {} -- 2.30.2