[cfe-dev] Patch to correct compilation errors related to class friend declarations

Tom Honermann thonermann at coverity.com
Sun Nov 6 18:47:45 PST 2011


On 11/5/2011 3:05 AM, John McCall wrote:
> On Nov 4, 2011, at 8:34 PM, Tom Honermann wrote:
>> I checked out cfe/trunk today and attempted a build using an older
>> gcc compiler (4.0.3) on Linux.  The build failed in a few places
>> with the errors below.  The attached patch corrects these.  Each of
>> the errors was related to class friend declarations.
>>
>> llvm-trunk/tools/clang/include/clang/Basic/Diagnostic.h:590: error: 'clang::DiagnosticsEngine::<anonymous enum> clang::DiagnosticsEngine::MaxArguments' is private
>> llvm-trunk/tools/clang/include/clang/Basic/PartialDiagnostic.h:36: error: within this context
>> llvm-trunk/tools/clang/include/clang/Basic/Diagnostic.h:621: error: 'clang::DiagnosticsEngine::<anonymous enum> clang::DiagnosticsEngine::MaxFixItHints' is private
>> llvm-trunk/tools/clang/include/clang/Basic/PartialDiagnostic.h:68: error: within this context
>>
>> This error looks legit to me.  The code appears to be violating
>> C++03 11.4.2 [class.friend] and 11.8.1 [class.access.nest].
>> Granting friendship to a class does not confer friendship to nested
>> classes of the befriended class.
>
> It does, actually: [class.access]p2: A member of a class can also
> access all the names to which the class has access.
> [class.access.nest]p1: A nested class is a member and as such has the
> same access rights as any other member. It's the other way that
> doesn't hold;  having access to a class doesn't give you access to
> its nested classes.

It looks like you are quoting from C++11 (or draft) and that the 
behavior has changed from C++03 (or, there was a CWG defect related to 
this?).  C++03 11.4.2 [class.friend] and 11.8.1 [class.access.nest] are 
explicit that friendship does not confer to nested classes of a 
befriended class.  The example from C++03 11.4.2 is:

     class A {
         class B { };
         friend class X;
     };
     class X : A::B {      // ill-formed: A::B cannot be accessed
                           // in the base-clause for X
         A::B mx;          // OK: A::B used to declare member of X
         class Y : A::B {  // OK: A::B used to declare member of X
             A::B my;      // ill-formed: A::B cannot be accessed
                           // to declare members of nested class of X
         };
     };

C++03 11.8.1 states: "The members of a nested class have no special 
access to members of an enclosing class, nor to classes or functions 
that have granted friendship to an enclosing class"

Tom.




More information about the cfe-dev mailing list