public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Patrick Palka <ppalka@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-8475] c++: access for hidden friend of nested class template [PR100502] Date: Fri, 28 May 2021 14:21:40 +0000 (GMT) [thread overview] Message-ID: <20210528142140.86F7A383D03B@sourceware.org> (raw) https://gcc.gnu.org/g:365deb8399262033ac766b924c35d31db3d621ca commit r11-8475-g365deb8399262033ac766b924c35d31db3d621ca Author: Patrick Palka <ppalka@redhat.com> Date: Wed May 26 16:02:33 2021 -0400 c++: access for hidden friend of nested class template [PR100502] Here, during ahead of time access checking for the private member EnumeratorRange<T>::end_reached_ in the hidden friend f, we're triggering the assert in enforce_access that verifies we're not trying to add a access check for a dependent decl onto TI_DEFERRED_ACCESS_CHECKS. The special thing about this class member access expression is that the overall expression is non-dependent (so finish_class_member_access_expr doesn't exit early at parse time), and then accessible_p rejects the access (so we don't exit early from enforce access either, and end up triggering the assert b/c the member itself is dependent). I think we're correct to reject the access because a hidden friend is not a member function, so [class.access.nest] doesn't apply, and also a hidden friend of a nested class is not a friend of the enclosing class. To fix this ICE, this patch disables ahead of time access checking during the member lookup in finish_class_member_access_expr. This avoids potentially pushing an access check for a dependent member onto TI_DEFERRED_ACCESS_CHECKS, and it's safe because we're going to redo the same lookup at instantiation time anyway. PR c++/100502 gcc/cp/ChangeLog: * typeck.c (finish_class_member_access_expr): Disable ahead of time access checking during the member lookup. gcc/testsuite/ChangeLog: * g++.dg/template/access37.C: New test. * g++.dg/template/access37a.C: New test. (cherry picked from commit abe8787a8492013145b275b858f70943522d7226) Diff: --- gcc/cp/typeck.c | 10 ++++++++++ gcc/testsuite/g++.dg/template/access37.C | 26 ++++++++++++++++++++++++++ gcc/testsuite/g++.dg/template/access37a.C | 6 ++++++ 3 files changed, 42 insertions(+) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 50d0f1e6a62..cce26b89cde 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3201,9 +3201,19 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, { /* Look up the member. */ access_failure_info afi; + if (processing_template_decl) + /* Even though this class member access expression is at this + point not dependent, the member itself may be dependent, and + we must not potentially push a access check for a dependent + member onto TI_DEFERRED_ACCESS_CHECKS. So don't check access + ahead of time here; we're going to redo this member lookup at + instantiation time anyway. */ + push_deferring_access_checks (dk_no_check); member = lookup_member (access_path, name, /*protect=*/1, /*want_type=*/false, complain, &afi); + if (processing_template_decl) + pop_deferring_access_checks (); afi.maybe_suggest_accessor (TYPE_READONLY (object_type)); if (member == NULL_TREE) { diff --git a/gcc/testsuite/g++.dg/template/access37.C b/gcc/testsuite/g++.dg/template/access37.C new file mode 100644 index 00000000000..5be532c75b0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access37.C @@ -0,0 +1,26 @@ +// PR c++/100502 + +template <class T> +struct EnumeratorRange { + struct Iterator { + 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" } + } + }; + + private: + bool end_reached_; +#if DECLARE_FRIEND + friend void f(Iterator); +#endif +}; + +int main() { + EnumeratorRange<int>::Iterator i; + f(i); +} diff --git a/gcc/testsuite/g++.dg/template/access37a.C b/gcc/testsuite/g++.dg/template/access37a.C new file mode 100644 index 00000000000..4ce1b2718a0 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/access37a.C @@ -0,0 +1,6 @@ +// PR c++/100502 +// { dg-additional-options "-DDECLARE_FRIEND -Wno-non-template-friend" } + +// Verify that access37.C is accepted if the appropriate friend relation +// is declared (controlled by the macro DECLARE_FRIEND). +#include "access37.C"
reply other threads:[~2021-05-28 14:21 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210528142140.86F7A383D03B@sourceware.org \ --to=ppalka@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).