From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2122) id 76034385B535; Sat, 22 Apr 2023 00:22:57 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 76034385B535 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1682122977; bh=kzBEjudSwQb6V8ImYr8B0wRzCruRjR/kP7zSheGGGX0=; h=From:To:Subject:Date:From; b=dWniBGUE8fS5DdupOOk48Sew4cjQ2CmfgnNMbZEe+TR0vEm2pzRUxXF/vOgDzMZjO ixa98Lku+XocQZ9NLrBFfA2L0EbzfSy3N00nBg6hBYFu2jq2lkyo9Kfq7JAtKQEEKU pieJ0Y9v6cqQKrAEu1/091hTjy9J6oD9vRIHB7xc= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jason Merrill To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-10644] c++: namespace-scoped friend in local class [PR69410] X-Act-Checkin: gcc X-Git-Author: Jason Merrill X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: 691e385b354482f3379bba471774873ca7179b79 X-Git-Newrev: fbf72bbaed4477f1e3881a8d25977dd3890015eb Message-Id: <20230422002257.76034385B535@sourceware.org> Date: Sat, 22 Apr 2023 00:22:57 +0000 (GMT) List-Id: https://gcc.gnu.org/g:fbf72bbaed4477f1e3881a8d25977dd3890015eb commit r11-10644-gfbf72bbaed4477f1e3881a8d25977dd3890015eb Author: Jason Merrill Date: Fri Mar 17 09:43:48 2023 -0400 c++: namespace-scoped friend in local class [PR69410] do_friend was only considering class-qualified identifiers for the qualified-id case, but we also need to skip local scope when there's an explicit namespace scope. PR c++/69410 gcc/cp/ChangeLog: * friend.c (do_friend): Handle namespace as scope argument. * decl.c (grokdeclarator): Pass down in_namespace. gcc/testsuite/ChangeLog: * g++.dg/lookup/friend24.C: New test. Diff: --- gcc/cp/decl.c | 3 ++- gcc/cp/friend.c | 21 +++++++++++++++++---- gcc/testsuite/g++.dg/lookup/friend24.C | 9 +++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 6c07cc2ad61..178f533a795 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -13888,7 +13888,8 @@ grokdeclarator (const cp_declarator *declarator, return error_mark_node; } - decl = do_friend (ctype, unqualified_id, decl, + tree scope = ctype ? ctype : in_namespace; + decl = do_friend (scope, unqualified_id, decl, *attrlist, flags, funcdef_flag); return decl; diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index ee73adb1677..e41def3a2ea 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -467,19 +467,32 @@ make_friend_class (tree type, tree friend_type, bool complain) } /* Record DECL (a FUNCTION_DECL) as a friend of the - CURRENT_CLASS_TYPE. If DECL is a member function, CTYPE is the + CURRENT_CLASS_TYPE. If DECL is a member function, SCOPE is the class of which it is a member, as named in the friend declaration. + If the friend declaration was explicitly namespace-qualified, SCOPE + is that namespace. DECLARATOR is the name of the friend. FUNCDEF_FLAG is true if the friend declaration is a definition of the function. FLAGS is as for grokclass fn. */ tree -do_friend (tree ctype, tree declarator, tree decl, +do_friend (tree scope, tree declarator, tree decl, tree attrlist, enum overload_flags flags, bool funcdef_flag) { gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); - gcc_assert (!ctype || MAYBE_CLASS_TYPE_P (ctype)); + + tree ctype = NULL_TREE; + tree in_namespace = NULL_TREE; + if (!scope) + ; + else if (MAYBE_CLASS_TYPE_P (scope)) + ctype = scope; + else + { + gcc_checking_assert (TREE_CODE (scope) == NAMESPACE_DECL); + in_namespace = scope; + } /* Friend functions are unique, until proved otherwise. */ DECL_UNIQUE_FRIEND_P (decl) = 1; @@ -606,7 +619,7 @@ do_friend (tree ctype, tree declarator, tree decl, parameters. Instead, we call pushdecl when the class is instantiated. */ decl = push_template_decl (decl, /*is_friend=*/true); - else if (current_function_decl) + else if (current_function_decl && !in_namespace) /* pushdecl will check there's a local decl already. */ decl = pushdecl (decl, /*hiding=*/true); else diff --git a/gcc/testsuite/g++.dg/lookup/friend24.C b/gcc/testsuite/g++.dg/lookup/friend24.C new file mode 100644 index 00000000000..9a45410d2a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/friend24.C @@ -0,0 +1,9 @@ +// PR c++/69410 + +void a(); +void f() { + class A { + friend void ::a(); + friend class Z; + }; +}