From 19db77cefec38a1a0a3eb69007f01e8a1c108d5d Mon Sep 17 00:00:00 2001 From: Kriang Lerdsuwanakij Date: Sat, 23 Aug 2003 12:53:48 +0000 Subject: PR c++/641, c++/11876 PR c++/641, c++/11876 * friend.c (add_friend): Add complain parameter. (make_friend_class): Likewise. (do_friend): Adjust add_friend call. * decl.c (grokdeclarator): Adjust make_friend_class call. * parser.c (cp_parser_member_declaration): Likewise. (cp_parser_template_declaration_after_exp): Likewise. * pt.c (instantiate_class_template): Adjust make_friend_class and add_friend call. * cp-tree.h (make_friend_class): Adjust declaration. (add_friend): Likewise. * g++.dg/template/friend22.C: New test. * g++.dg/template/friend23.C: Likewise. From-SVN: r70732 --- gcc/cp/ChangeLog | 14 +++++++++ gcc/cp/cp-tree.h | 4 +-- gcc/cp/decl.c | 3 +- gcc/cp/friend.c | 49 +++++++++++++++++++++----------- gcc/cp/parser.c | 6 ++-- gcc/cp/pt.c | 6 ++-- gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/g++.dg/template/friend22.C | 15 ++++++++++ gcc/testsuite/g++.dg/template/friend23.C | 38 +++++++++++++++++++++++++ 9 files changed, 117 insertions(+), 24 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/friend22.C create mode 100644 gcc/testsuite/g++.dg/template/friend23.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7eaf150..ad2cdbc 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,17 @@ +2003-08-23 Kriang Lerdsuwanakij + + PR c++/641, c++/11876 + * friend.c (add_friend): Add complain parameter. + (make_friend_class): Likewise. + (do_friend): Adjust add_friend call. + * decl.c (grokdeclarator): Adjust make_friend_class call. + * parser.c (cp_parser_member_declaration): Likewise. + (cp_parser_template_declaration_after_exp): Likewise. + * pt.c (instantiate_class_template): Adjust make_friend_class + and add_friend call. + * cp-tree.h (make_friend_class): Adjust declaration. + (add_friend): Likewise. + 2003-08-21 Jason Merrill PR c++/11283 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 9cda769..025277e 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3840,8 +3840,8 @@ extern tree cplus_expand_constant (tree); /* friend.c */ extern int is_friend (tree, tree); -extern void make_friend_class (tree, tree); -extern void add_friend (tree, tree); +extern void make_friend_class (tree, tree, bool); +extern void add_friend (tree, tree, bool); extern tree do_friend (tree, tree, tree, tree, tree, enum overload_flags, tree, int); /* in init.c */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index e35fa07..dc3495f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11252,7 +11252,8 @@ grokdeclarator (tree declarator, { /* A friendly class? */ if (current_class_type) - make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type)); + make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type), + /*complain=*/true); else error ("trying to make class `%T' a friend of global scope", type); diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index b71c5f2..1b3d4b4 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -127,10 +127,14 @@ is_friend (tree type, tree supplicant) } /* Add a new friend to the friends of the aggregate type TYPE. - DECL is the FUNCTION_DECL of the friend being added. */ + DECL is the FUNCTION_DECL of the friend being added. + + If COMPLAIN is true, warning about duplicate friend is issued. + We want to have this diagnostics during parsing but not + when a template is being instantiated. */ void -add_friend (tree type, tree decl) +add_friend (tree type, tree decl, bool complain) { tree typedecl; tree list; @@ -153,10 +157,13 @@ add_friend (tree type, tree decl) { if (decl == TREE_VALUE (friends)) { - warning ("`%D' is already a friend of class `%T'", - decl, type); - cp_warning_at ("previous friend declaration of `%D'", - TREE_VALUE (friends)); + if (complain) + { + warning ("`%D' is already a friend of class `%T'", + decl, type); + cp_warning_at ("previous friend declaration of `%D'", + TREE_VALUE (friends)); + } return; } } @@ -192,10 +199,14 @@ add_friend (tree type, tree decl) classes that are not defined. If a type has not yet been defined, then the DECL_WAITING_FRIENDS contains a list of types waiting to make it their friend. Note that these two can both - be in use at the same time! */ + be in use at the same time! + + If COMPLAIN is true, warning about duplicate friend is issued. + We want to have this diagnostics during parsing but not + when a template is being instantiated. */ void -make_friend_class (tree type, tree friend_type) +make_friend_class (tree type, tree friend_type, bool complain) { tree classes; int is_template_friend; @@ -227,8 +238,9 @@ make_friend_class (tree type, tree friend_type) } else if (same_type_p (type, friend_type)) { - pedwarn ("class `%T' is implicitly friends with itself", - type); + if (complain) + pedwarn ("class `%T' is implicitly friends with itself", + type); return; } else @@ -275,8 +287,9 @@ make_friend_class (tree type, tree friend_type) { if (friend_type == probe) { - warning ("`%D' is already a friend of `%T'", - probe, type); + if (complain) + warning ("`%D' is already a friend of `%T'", + probe, type); break; } } @@ -284,8 +297,9 @@ make_friend_class (tree type, tree friend_type) { if (same_type_p (probe, friend_type)) { - warning ("`%T' is already a friend of `%T'", - probe, type); + if (complain) + warning ("`%T' is already a friend of `%T'", + probe, type); break; } } @@ -369,7 +383,7 @@ do_friend (tree ctype, tree declarator, tree decl, tree parmdecls, parameters. Instead, we rely on tsubst_friend_function to check the validity of the declaration later. */ if (processing_template_decl) - add_friend (current_class_type, decl); + add_friend (current_class_type, decl, /*complain=*/true); /* A nested class may declare a member of an enclosing class to be a friend, so we do lookup here even if CTYPE is in the process of being defined. */ @@ -378,7 +392,7 @@ do_friend (tree ctype, tree declarator, tree decl, tree parmdecls, decl = check_classfn (ctype, decl); if (decl) - add_friend (current_class_type, decl); + add_friend (current_class_type, decl, /*complain=*/true); } else error ("member `%D' declared as friend before type `%T' defined", @@ -446,7 +460,8 @@ do_friend (tree ctype, tree declarator, tree decl, tree parmdecls, } add_friend (current_class_type, - is_friend_template ? DECL_TI_TEMPLATE (decl) : decl); + is_friend_template ? DECL_TI_TEMPLATE (decl) : decl, + /*complain=*/true); DECL_FRIEND_P (decl) = 1; } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index c177a6c..1fb1a51 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -11840,7 +11840,8 @@ cp_parser_member_declaration (cp_parser* parser) error ("friend declaration does not name a class or " "function"); else - make_friend_class (current_class_type, type); + make_friend_class (current_class_type, type, + /*complain=*/true); } /* If there is no TYPE, an error message will already have been issued. */ @@ -13636,7 +13637,8 @@ cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p) if (member_p && !friend_p && decl) decl = finish_member_template_decl (decl); else if (friend_p && decl && TREE_CODE (decl) == TYPE_DECL) - make_friend_class (current_class_type, TREE_TYPE (decl)); + make_friend_class (current_class_type, TREE_TYPE (decl), + /*complain=*/true); } /* We are done with the current parameter list. */ --parser->num_template_parameter_lists; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index c66b5bc..d6ea8cc 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5381,14 +5381,16 @@ instantiate_class_template (tree type) ++processing_template_decl; if (new_friend_type != error_mark_node) - make_friend_class (type, new_friend_type); + make_friend_class (type, new_friend_type, + /*complain=*/false); if (TREE_CODE (friend_type) == TEMPLATE_DECL) --processing_template_decl; } else /* Build new DECL_FRIENDLIST. */ - add_friend (type, tsubst_friend_function (t, args)); + add_friend (type, tsubst_friend_function (t, args), + /*complain=*/false); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3ec6c04..c25f750 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2003-08-23 Kriang Lerdsuwanakij + + PR c++/641, c++/11876 + * g++.dg/template/friend22.C: New test. + * g++.dg/template/friend23.C: Likewise. + 2003-08-22 Mark Mitchell * gcc.misc-tests/linkage.exp: Treat all HP-UX platforms diff --git a/gcc/testsuite/g++.dg/template/friend22.C b/gcc/testsuite/g++.dg/template/friend22.C new file mode 100644 index 0000000..41a73bb --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend22.C @@ -0,0 +1,15 @@ +// { dg-do compile } + +// Origin: Benoit Hudson + +// PR c++/641: Duplicate friend diagnostics + +template class iterator { }; +template class item { + friend class iterator; + friend class iterator; +}; + +class A { }; + +item i; diff --git a/gcc/testsuite/g++.dg/template/friend23.C b/gcc/testsuite/g++.dg/template/friend23.C new file mode 100644 index 0000000..96f8125 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/friend23.C @@ -0,0 +1,38 @@ +// { dg-do compile } + +// Origin: Alexandre Tolmos + +// PR c++/11876: Friend of its own class diagnostics + +template +class A +{ + friend class A; + friend class A; +protected: + T _data; + inline A() : _data(0) {} + template + inline A(const A& r) : _data(r._data) {} +}; + +class B : public A +{ +public: + inline B() {} + inline B(const B& r) : A(r) {} +}; + +class C : public A +{ +public: + inline C() {} + inline C(const B& r) : A(r) {} +}; + +int main(int, char*[]) +{ + B b1, b2(b1); + C c(b1); + return 0; +} -- cgit v1.1