From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 56896 invoked by alias); 20 Aug 2015 20:54:45 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 56879 invoked by uid 89); 20 Aug 2015 20:54:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.3 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 20 Aug 2015 20:54:44 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id E24F7AA0A4 for ; Thu, 20 Aug 2015 20:54:42 +0000 (UTC) Received: from [10.10.116.45] (ovpn-116-45.rdu2.redhat.com [10.10.116.45]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t7KKsg36001441 for ; Thu, 20 Aug 2015 16:54:42 -0400 To: gcc-patches List From: Jason Merrill Subject: C++ PATCH to overloaded friend hiding Message-ID: <55D63E91.8040309@redhat.com> Date: Thu, 20 Aug 2015 20:58:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------080501080505020400050704" X-SW-Source: 2015-08/txt/msg01252.txt.bz2 This is a multi-part message in MIME format. --------------080501080505020400050704 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 201 Someone on the C++ committee pointed out that G++ unqualified lookup could see through one hidden friend, but not two, and not a template. Fixed thus. Tested x86_64-pc-linux-gnu, applying to trunk. --------------080501080505020400050704 Content-Type: text/x-patch; name="friend.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="friend.patch" Content-length: 2999 commit bef61f4085710822782a462def4a7032c8a91668 Author: Jason Merrill Date: Thu Aug 20 14:40:55 2015 -0400 * name-lookup.c (hidden_name_p): Handle OVERLOAD. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 79e2863..baaf3e7 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4346,6 +4346,13 @@ hidden_name_p (tree val) && TYPE_FUNCTION_OR_TEMPLATE_DECL_P (val) && DECL_ANTICIPATED (val)) return true; + if (TREE_CODE (val) == OVERLOAD) + { + for (tree o = val; o; o = OVL_CHAIN (o)) + if (!hidden_name_p (OVL_FUNCTION (o))) + return false; + return true; + } return false; } diff --git a/gcc/testsuite/g++.dg/lookup/friend16.C b/gcc/testsuite/g++.dg/lookup/friend16.C new file mode 100644 index 0000000..bb27773 --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/friend16.C @@ -0,0 +1,24 @@ +namespace std { + class ostream; +} + +namespace N2 { + class C0 {}; +} + +std::ostream& operator<<( std::ostream& os_, const N2::C0& m_); + +namespace N1 { + class C1 { + friend std::ostream& operator<<(std::ostream& os, const C1& what); + }; + + class C2 { + friend std::ostream& operator<<(std::ostream& os, const C2& what); + }; + + void foo(std::ostream & os, const N2::C0& m) + { + os << m; // Is this line valid? + } +} diff --git a/gcc/testsuite/g++.dg/template/friend15.C b/gcc/testsuite/g++.dg/template/friend15.C index 4acbf2d..15ba1c2 100644 --- a/gcc/testsuite/g++.dg/template/friend15.C +++ b/gcc/testsuite/g++.dg/template/friend15.C @@ -10,10 +10,11 @@ template class X { struct Inner; template - friend typename X::Inner * foo () { return 0; } + friend typename X::Inner * foo (X*) { return 0; } }; template class X; +X* p; struct U { - void bar () { foo (); } + void bar () { foo (p); } }; diff --git a/gcc/testsuite/g++.dg/template/friend18.C b/gcc/testsuite/g++.dg/template/friend18.C index 04ba26e..712d488 100644 --- a/gcc/testsuite/g++.dg/template/friend18.C +++ b/gcc/testsuite/g++.dg/template/friend18.C @@ -7,13 +7,14 @@ template struct X { - template friend int foo(X const &) + template friend int foo(X const &, X const&) { return N * 10000 + M; } }; X<1234> bring; +X<5678> brung; int main() { - return foo<5678> (bring) != 12345678; + return foo (bring, brung) != 12345678; } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend32.C b/gcc/testsuite/g++.old-deja/g++.pt/friend32.C index 512a69a..db8b724 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/friend32.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/friend32.C @@ -7,8 +7,8 @@ struct S { }; template class S; -template char f(char, long, short); -template char* f(char*, long*, short*); +template char f(char, long, short); // { dg-error "f" } +template char* f(char*, long*, short*); // { dg-error "f" } template X f(X x, Y, Z) { --------------080501080505020400050704--