diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 703ddd3cc7a..3df4117e4e7 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 +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::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"