From patchwork Sun May 15 16:44:51 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 53993 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 989923857820 for ; Sun, 15 May 2022 16:45:27 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 989923857820 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1652633127; bh=8RdW5yPbVeZejk6U5M7EvMc331su/bhhIIWNCfkEP1Q=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=FkYOBcmYImeqQvFOKrs3eFfSXuETp2fjKKPrhukgXnVzD/q/yhS4ygHXAfbUZYH0P brkjyroGD1LfCrp+F3CaMKvvfYwEH3sGs5OLRTMYGHxrX3r+cHappP/PXurBSGNo4R wTYAjxK+o4jDYRHX0+gsTJgXCWvqpIEoeWQ+VZJE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 33ED73858D32 for ; Sun, 15 May 2022 16:44:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 33ED73858D32 Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-60-zovYm8q8Nlyd1iGZMCgnAQ-1; Sun, 15 May 2022 12:44:54 -0400 X-MC-Unique: zovYm8q8Nlyd1iGZMCgnAQ-1 Received: by mail-qv1-f70.google.com with SMTP id o99-20020a0c906c000000b00456332167ffso6030727qvo.13 for ; Sun, 15 May 2022 09:44:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=8RdW5yPbVeZejk6U5M7EvMc331su/bhhIIWNCfkEP1Q=; b=N1p6eV4ZokP3P7fidpbIkZ2A5r4iC3T6+5w42OTnBuCLX2pRPrGWfQnDRZ9m8tqXy7 LDJKC16lvXjC/vv6awJA8T2fZcyeYWetSpE+0kneRfIh6kIbhA1avmBLByY2U7WlYDra brv0w0q0PebDoi0A5mydKAnbRmY9Dh4j8FH4JtYj4Pt4z5HnhdbpUY9T6bA/uO6VyDLD 1Inr2caYLk4ql1HnibYtfzAg3UUT5/qAtwE17uIFl+CdT15r1Vm6FhGi5Kug+AAQvt1m 7y0tyl8Cz/2lYhFz/SsTcstoAFbsNRBvfiDPW95yke/L+ybBoi4fClTrJqRYum5xtgRq LAHw== X-Gm-Message-State: AOAM532jEYGy/ASsAerszoYT0bZhgfQgqDLNLU/QyMdpSGZfiNqeaf2O kmF+PjtAAFavvpcAndmh0iWVViQqsuCtk6Mc9jiBYEEDUc6G/Br1/ETsP65OalSFnquqaMAHMxE 2wIQ8L4zZmOWd9FtJlSbV9rReLJ4VUbqQHOc4R+rO5eQ3vDx0rxkJpojzi3xYNCJ6sw== X-Received: by 2002:a05:620a:1a97:b0:69e:b83e:bb9a with SMTP id bl23-20020a05620a1a9700b0069eb83ebb9amr9917481qkb.711.1652633093823; Sun, 15 May 2022 09:44:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzFnjzUAbUDD6NMMp6UvVx1j6HmpFXEqTruLUnI9OJaPnx4AR8sgwgOQmNsbinjFGOy57+XUQ== X-Received: by 2002:a05:620a:1a97:b0:69e:b83e:bb9a with SMTP id bl23-20020a05620a1a9700b0069eb83ebb9amr9917467qkb.711.1652633093396; Sun, 15 May 2022 09:44:53 -0700 (PDT) Received: from barrymore.redhat.com (130-44-159-43.s15913.c3-0.arl-cbr1.sbo-arl.ma.cable.rcncustomer.com. [130.44.159.43]) by smtp.gmail.com with ESMTPSA id h3-20020a05620a284300b0069ffe63228fsm4398831qkp.121.2022.05.15.09.44.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 15 May 2022 09:44:52 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [pushed] c++: hidden friend access [DR1699] Date: Sun, 15 May 2022 12:44:51 -0400 Message-Id: <20220515164451.3971995-1-jason@redhat.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jason Merrill via Gcc-patches From: Jason Merrill Reply-To: Jason Merrill Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" It has come up several times that Clang considers hidden friends of a class to be sufficiently memberly to be covered by a friend declaration naming the class. This is somewhat unclear in the standard: [class.friend] says "Declaring a class to be a friend implies that private and protected members of the class granting friendship can be named in the base-specifiers and member declarations of the befriended class." A hidden friend is a syntactic member-declaration, but is it a "member declaration"? CWG was ambivalent, and referred the question to EWG as a design choice. But recently Patrick mentioned that the current G++ choice not to treat it as a "member declaration" was making his library work significantly more cumbersome, so let's go ahead and vote the other way. This means that the testcases for 100502 and 58993 are now accepted. Tested x86_64-pc-linux-gnu, applying to trunk. DR1699 PR c++/100502 PR c++/58993 gcc/cp/ChangeLog: * friend.cc (is_friend): Hidden friends count as members. * search.cc (friend_accessible_p): Likewise. gcc/testsuite/ChangeLog: * g++.dg/template/access37.C: Now OK. * g++.dg/template/friend69.C: Now OK. * g++.dg/lookup/friend23.C: New test. --- gcc/cp/friend.cc | 2 ++ gcc/cp/search.cc | 7 ++----- gcc/testsuite/g++.dg/lookup/friend23.C | 17 +++++++++++++++++ gcc/testsuite/g++.dg/template/access37.C | 8 ++++---- gcc/testsuite/g++.dg/template/friend69.C | 4 ++-- 5 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/lookup/friend23.C base-commit: ce46d6041358052dfa26f3720732f0357c5d72e7 prerequisite-patch-id: 4e382fc8327c2191fe57f2111af0c9830dc85d71 diff --git a/gcc/cp/friend.cc b/gcc/cp/friend.cc index 124ed4f3962..bf37dadeb62 100644 --- a/gcc/cp/friend.cc +++ b/gcc/cp/friend.cc @@ -131,6 +131,8 @@ is_friend (tree type, tree supplicant) { if (DECL_FUNCTION_MEMBER_P (supplicant)) context = DECL_CONTEXT (supplicant); + else if (tree fc = DECL_FRIEND_CONTEXT (supplicant)) + context = fc; else context = NULL_TREE; } diff --git a/gcc/cp/search.cc b/gcc/cp/search.cc index b86b3a24080..10863a40b11 100644 --- a/gcc/cp/search.cc +++ b/gcc/cp/search.cc @@ -734,12 +734,9 @@ friend_accessible_p (tree scope, tree decl, tree type, tree otype) && friend_accessible_p (DECL_CONTEXT (scope), decl, type, otype)) return 1; /* Perhaps SCOPE is a friend function defined inside a class from which - DECL is accessible. Checking this is necessary only when the class - is dependent, for otherwise add_friend will already have added the - class to SCOPE's DECL_BEFRIENDING_CLASSES. */ + DECL is accessible. */ if (tree fctx = DECL_FRIEND_CONTEXT (scope)) - if (dependent_type_p (fctx) - && protected_accessible_p (decl, fctx, type, otype)) + if (friend_accessible_p (fctx, decl, type, otype)) return 1; } diff --git a/gcc/testsuite/g++.dg/lookup/friend23.C b/gcc/testsuite/g++.dg/lookup/friend23.C new file mode 100644 index 00000000000..f7b26c9e3ae --- /dev/null +++ b/gcc/testsuite/g++.dg/lookup/friend23.C @@ -0,0 +1,17 @@ +template +struct base { + friend void bar(Derived& d) { + d.bar(); // access in inline friend of friend, ok? + } +}; + +class derived : base { + friend class base; + void bar() {} +}; + +int main() { + derived d; + bar(d); +} + diff --git a/gcc/testsuite/g++.dg/template/access37.C b/gcc/testsuite/g++.dg/template/access37.C index 5be532c75b0..407a7dc0f2d 100644 --- a/gcc/testsuite/g++.dg/template/access37.C +++ b/gcc/testsuite/g++.dg/template/access37.C @@ -6,10 +6,10 @@ struct EnumeratorRange { EnumeratorRange range_; friend void f(Iterator i) { - i.range_.end_reached_; // { dg-error "private" } - i.range_.EnumeratorRange::end_reached_; // { dg-error "private" } - &i.range_.end_reached_; // { dg-error "private" } - &i.range_.EnumeratorRange::end_reached_; // { dg-error "private" } + i.range_.end_reached_; + i.range_.EnumeratorRange::end_reached_; + &i.range_.end_reached_; + &i.range_.EnumeratorRange::end_reached_; } }; diff --git a/gcc/testsuite/g++.dg/template/friend69.C b/gcc/testsuite/g++.dg/template/friend69.C index f3086a9f980..9bec6ba5846 100644 --- a/gcc/testsuite/g++.dg/template/friend69.C +++ b/gcc/testsuite/g++.dg/template/friend69.C @@ -12,7 +12,7 @@ protected: struct A { friend void g(A) { - B::f(); // { dg-error "private" } - B::g(); // { dg-error "protected" } + B::f(); + B::g(); } };