http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57593
--- Comment #2 from David Krauss <potswa at mac dot com> --- The maintainer (Mike Miller at EDG) said simply that he will add it to the list, but as far as I know a number isn't assigned until the new list is drafted. The title is "access granted by friendship to class-scope friend declaration." (But I suppose he could take a liberty and remove the redundant "class-scope".) Regardless of any possible defect, GCC is inconsistent. The change in access applies to certain declarations, not others, but GCC is applying it to parts of certain declarations (seemingly only the function body is excluded). To be consistent with the current standard, the only choices are to allow all 3 examples or disallow all 3. The latter choice would be a nasty breaking change. If it helps, here is the text of DR submission. ---- Friendship is not transitive, but it does grant access to "member declarations of the befriended class." ([class.friend]/2) And a friend is declared by a member-declaration. Is a grammatical member-declaration with the friend specifier still a member declaration? class c { class n {}; friend struct s; }; struct s { friend class c::n; // 1 friend c::n g(); // 2 friend void f() { c::n(); } // 3 }; If a friend member-declaration is not a member declaration, then it is impossible to grant access to a private nested class (1) or a function composed from a type specified using a private nested class (2). Both GCC and Clang allow these examples. If a friend member-declaration is a member declaration, then it implements one degree of transitive friendship, if it is also a definition (3). Clang accepts this example, but GCC rejects it. Friends are enough like members that the access should apply. One common application is operator<< . A manipulator proxy class may need access from its insertion operator to its client's restricted members. Another application is to define a function that would otherwise be a nonstatic member but receives a container or smart pointer, not a direct reference to the object. These are the most common cases for the inline friend definition syntax. They are found by ADL so the namespace-scope declaration may be omitted. Working around by befriending the pseudo-member friend may be troublesome as it may violate separation of concerns, form undesired associated classes for ADL, or require forming a declaration which may use inconvenient nested types or reduplicated SFINAE. Although access control isn't really a security mechanism, no "exploit" would be opened by granting access because a friend can always delegate to a static member anyway. Proposed resolution: Modify [class.friend]: … can be accessed in the base-specifiers, member-declarations, and definitions of members of the befriended class. Is there any context within a class-specifier where access control is performed besides its base-specifiers and member-declarations? It doesn't seem to apply to name lookup in the template-name of a partial or explicit specialization, but I can't find the spec. Perhaps it should be: … can be accessed in the class-specifier and definitions of members of the befriended class.