diff options
author | Jason Merrill <jason@redhat.com> | 2021-02-05 10:36:49 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2021-04-29 14:38:50 -0400 |
commit | a0fdff3cf33f72848d3f894272431a5d49fe6a16 (patch) | |
tree | 1a9a9a3c4757ea89f59abca94553403318d1f79c /gcc/cp/decl2.c | |
parent | 58a92b789a77cdade1f41800efebf6e0686f9982 (diff) | |
download | gcc-a0fdff3cf33f72848d3f894272431a5d49fe6a16.zip gcc-a0fdff3cf33f72848d3f894272431a5d49fe6a16.tar.gz gcc-a0fdff3cf33f72848d3f894272431a5d49fe6a16.tar.bz2 |
c++: Fix friend attributes [PR51344]
51344 was a problem with calling save_template_attributes twice for the same
friend function: once from do_friend and once from grokmethod. The 2012
patch for the bug avoided creating an infinite loop when this happens, but
it's better to avoid the duplication in the first place. This also restores
the dependent attributes to the beginning of the attribute list, as
originally intended. And then apply_late_template_attributes can avoid
copying the non-dependent attributes.
gcc/cp/ChangeLog:
PR c++/51344
* decl2.c (grokfield): Call cplus_decl_attributes for friend.
(save_template_attributes): Use chainon.
* friend.c (do_friend): Remove attrlist parm.
* cp-tree.h (do_friend): Adjust.
* class.c (add_implicitly_declared_members): Adjust.
* decl.c (grokdeclarator): Adjust.
* pt.c (apply_late_template_attributes): Optimize.
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r-- | gcc/cp/decl2.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index a82960f..89f874a 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -974,7 +974,11 @@ grokfield (const cp_declarator *declarator, if ((TREE_CODE (value) == FUNCTION_DECL || TREE_CODE (value) == TEMPLATE_DECL) && DECL_CONTEXT (value) != current_class_type) - return value; + { + if (attrlist) + cplus_decl_attributes (&value, attrlist, 0); + return value; + } /* Need to set this before push_template_decl. */ if (VAR_P (value)) @@ -1278,9 +1282,9 @@ save_template_attributes (tree *attr_p, tree *decl_p, int flags) tree old_attrs = *q; - /* Merge the late attributes at the beginning with the attribute + /* Place the late attributes at the beginning of the attribute list. */ - late_attrs = merge_attributes (late_attrs, *q); + late_attrs = chainon (late_attrs, *q); if (*q != late_attrs && !DECL_P (*decl_p) && !(flags & ATTR_FLAG_TYPE_IN_PLACE)) |