testcase below has struct R as private in class F. class F declares class Q a friend, allowing it to see it's private members. But operator<< is friend in Q, not in F. Why is it allowed for operator<< to instantiate list<R> but not R r? This is a bug. --- testcase --- #include <list> #include <ostream> using namespace std; class F { private: struct R { }; // R friend class Q; class Q { list<R> l; friend ostream& operator<<(ostream &os, const Q &q) { // R r; // this breaks! for (list<R>::const_iterator it = q.l.begin(); it != q.l.end(); it++) { // this doesn't break! Why? } return os; } }; // Q }; // F
(In reply to comment #0) > class F declares class Q a friend There's no need for that, Q is a member of F so has access like any other member. Reduced: template<class T> struct list { struct nested { }; }; class F { struct R { }; class Q { friend void f(const Q &q) { list<R>::nested n; } }; };
Here's another variation that should fail but doesn't, showing this has nothing to do with friends: template<class T> struct list { struct nested { }; }; class F { struct R { }; }; void f() { list<F::R>::nested n; } list<F::R>::nested n; I've changed the summary to reflect this
Created attachment 29671 [details] patch Simple fix, waiting for 4.8 to branch.
Author: jason Date: Sun Mar 17 02:39:22 2013 New Revision: 196744 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=196744 Log: PR c++/45917 * parser.c (cp_parser_template_id): Don't forget access checks. Added: trunk/gcc/testsuite/g++.dg/template/access26.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/parser.c
*** Bug 56687 has been marked as a duplicate of this bug. ***
Fixed for 4.9.