From 0c0aac2fecce30d1c71554169446cae25f079234 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sat, 27 Mar 1999 17:33:36 +0000 Subject: [PATCH] cp-tree.h (add_friend): Declare. * cp-tree.h (add_friend): Declare. (add_friends): Likewise. * friend.c (add_friend): Make it global. Don't add to DECL_BEFRIENDING_CLASSES if the befriending class is a template. (add_friends): Make it global. (make_friend_class): Don't add to DECL_BEFRIENDING_CLASSES if the befriending class is a template. * parse.y (component_decl_1): Fix typo in comment. * parse.c: Regenerated. * pt.c (instantiate_class_template): Use add_friend and add_friends rather that duplicating some of their functionality here. From-SVN: r26020 --- gcc/cp/ChangeLog | 15 +++++++++ gcc/cp/cp-tree.h | 2 ++ gcc/cp/friend.c | 21 ++++++------- gcc/cp/parse.y | 2 +- gcc/cp/pt.c | 33 ++++++-------------- gcc/testsuite/g++.old-deja/g++.pt/crash32.C | 13 ++++++++ gcc/testsuite/g++.old-deja/g++.pt/friend38.C | 4 +-- 7 files changed, 52 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/crash32.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0138c8461b4..96970ed736e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +1999-03-27 Mark Mitchell + + * cp-tree.h (add_friend): Declare. + (add_friends): Likewise. + * friend.c (add_friend): Make it global. Don't add to + DECL_BEFRIENDING_CLASSES if the befriending class is a template. + (add_friends): Make it global. + (make_friend_class): Don't add to DECL_BEFRIENDING_CLASSES if the + befriending class is a template. + * parse.y (component_decl_1): Fix typo in comment. + * parse.c: Regenerated. + * pt.c (instantiate_class_template): Use add_friend and + add_friends rather that duplicating some of their functionality + here. + 1999-03-27 Jason Merrill * call.c (build_field_call): Unify 'this' and non-'this' cases. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4e6c024cc41..9bbf39ee3d5 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3028,6 +3028,8 @@ extern void do_case PROTO((tree, tree)); /* friend.c */ extern int is_friend PROTO((tree, tree)); extern void make_friend_class PROTO((tree, tree)); +extern void add_friend PROTO((tree, tree)); +extern void add_friends PROTO((tree, tree, tree)); extern tree do_friend PROTO((tree, tree, tree, tree, enum overload_flags, tree, int)); /* in init.c */ diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index 2a69acd8d84..285432f5ccd 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -27,9 +27,6 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "toplev.h" -static void add_friend PROTO((tree, tree)); -static void add_friends PROTO((tree, tree, tree)); - /* Friend data structures are described in cp-tree.h. */ /* Returns non-zero if SUPPLICANT is a friend of TYPE. */ @@ -140,7 +137,7 @@ is_friend (type, supplicant) /* Add a new friend to the friends of the aggregate type TYPE. DECL is the FUNCTION_DECL of the friend being added. */ -static void +void add_friend (type, decl) tree type, decl; { @@ -176,15 +173,16 @@ add_friend (type, decl) DECL_FRIENDLIST (typedecl) = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl), DECL_FRIENDLIST (typedecl)); - DECL_BEFRIENDING_CLASSES (decl) - = tree_cons (NULL_TREE, type, - DECL_BEFRIENDING_CLASSES (decl)); + if (!uses_template_parms (type)) + DECL_BEFRIENDING_CLASSES (decl) + = tree_cons (NULL_TREE, type, + DECL_BEFRIENDING_CLASSES (decl)); } /* Declare that every member function NAME in FRIEND_TYPE (which may be NULL_TREE) is a friend of type TYPE. */ -static void +void add_friends (type, name, friend_type) tree type, name, friend_type; { @@ -298,9 +296,10 @@ make_friend_class (type, friend_type) = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type)); if (is_template_friend) friend_type = TREE_TYPE (friend_type); - CLASSTYPE_BEFRIENDING_CLASSES (friend_type) - = tree_cons (NULL_TREE, type, - CLASSTYPE_BEFRIENDING_CLASSES (friend_type)); + if (!uses_template_parms (type)) + CLASSTYPE_BEFRIENDING_CLASSES (friend_type) + = tree_cons (NULL_TREE, type, + CLASSTYPE_BEFRIENDING_CLASSES (friend_type)); } } diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 9e10c106682..7ef6984b931 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -2483,7 +2483,7 @@ component_decl_1: Therefore, the rules for components take care of this processing. To avoid registering the components more than once, we send NULL_TREE up - here; that lets finish_member_declaration now + here; that lets finish_member_declaration know that there is nothing to do. */ if (!$2) grok_x_components ($1.t); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 8d83ffafcb5..8855efa311e 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -4961,32 +4961,19 @@ instantiate_class_template (type) { tree friends; - DECL_FRIENDLIST (typedecl) - = tree_cons (TREE_PURPOSE (t), NULL_TREE, - DECL_FRIENDLIST (typedecl)); - for (friends = TREE_VALUE (t); friends != NULL_TREE; friends = TREE_CHAIN (friends)) - { - if (TREE_PURPOSE (friends) == error_mark_node) - { - TREE_VALUE (DECL_FRIENDLIST (typedecl)) - = tree_cons (error_mark_node, - tsubst_friend_function (TREE_VALUE (friends), - args), - TREE_VALUE (DECL_FRIENDLIST (typedecl))); - } - else - { - TREE_VALUE (DECL_FRIENDLIST (typedecl)) - = tree_cons (tsubst (TREE_PURPOSE (friends), args, - /*complain=*/1, NULL_TREE), - NULL_TREE, - TREE_VALUE (DECL_FRIENDLIST (typedecl))); - - } - } + if (TREE_PURPOSE (friends) == error_mark_node) + add_friend (type, + tsubst_friend_function (TREE_VALUE (friends), + args)); + else + add_friends (type, + tsubst_copy (TREE_PURPOSE (t), args, + /*complain=*/1, NULL_TREE), + tsubst (TREE_PURPOSE (friends), args, + /*complain=*/1, NULL_TREE)); } for (t = CLASSTYPE_FRIEND_CLASSES (pattern); diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash32.C b/gcc/testsuite/g++.old-deja/g++.pt/crash32.C new file mode 100644 index 00000000000..68cf4df6fb2 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash32.C @@ -0,0 +1,13 @@ +// Build don't link: +// Origin: Jason Merrill + +template struct A +{ + struct B; +}; + +template struct C +{ + friend typename A::B; +}; + diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend38.C b/gcc/testsuite/g++.old-deja/g++.pt/friend38.C index 41c7714acc5..e3a6a060ef6 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/friend38.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/friend38.C @@ -2,9 +2,7 @@ // Overly simplified from testcase by "B. K. Oxley" -// crash test - XFAIL *-*-* - template struct foo { typedef P parent_type; - friend parent_type; // ERROR - template parameters cannot be friends + friend parent_type; // ERROR - template parameters cannot be friends - XFAIL *-*-* }; -- 2.30.2