aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2021-02-05 10:36:49 -0500
committerJason Merrill <jason@redhat.com>2021-04-29 14:38:50 -0400
commita0fdff3cf33f72848d3f894272431a5d49fe6a16 (patch)
tree1a9a9a3c4757ea89f59abca94553403318d1f79c /gcc/cp/decl2.c
parent58a92b789a77cdade1f41800efebf6e0686f9982 (diff)
downloadgcc-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.c10
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))