[cfe-dev] [PATCH] Friend class cannot access protected field of parent

John McCall rjmccall at apple.com
Tue Jun 8 12:09:46 PDT 2010


On Jun 8, 2010, at 11:29 AM, Olivier Goffart wrote:

> Le Tuesday 08 June 2010, John McCall a écrit :
>> On Jun 8, 2010, at 1:56 AM, Olivier Goffart wrote:
>>> Le Tuesday 08 June 2010, John McCall a écrit :
>>>> On Jun 8, 2010, at 12:23 AM, Olivier Goffart wrote:
>>>>> So you think it is better not to try to make it work, even for the non-
>>>>> template case?
>>>> 
>>>> Yes.  Like I said, I don't think this is an intended feature;  I think
>>>> it's a drafting error.  [class.access.base] contains many repetitions
>>>> of the phrase "member or friend";  I think someone just wrote "member
>>>> or friend" here without really thinking.  I think when they were
>>>> drafting the example in [class.protected] they were only thinking about
>>>> the effect of the protected access restriction, not whether the member
>>>> itself was accessible from the naming class.  I'm willing to consider
>>>> evidence in the form of a DR that I'm wrong, but I don't really want to
>>>> implement the rule, and I'm not going to implement it as long as it's
>>>> undecidable.
>>> 
>>> Alright.
>>> Still, according to the examples in [class.protected], it does not seem
>>> to be a simple mistake.
>> 
>> Right, I acknowledge that.
>> 
>> For what it's worth, your patch looks pretty good, except (1) I don't see
>> how you're dealing with multiple declarations of the target function/record 
> 
> I don't know what you mean here, can you elaborate?

There should be one linked list of "reverse friends" per function or record, right?
Except every separate declaration of a record or function becomes a separate Decl
node, and each Decl node has its own list root.  Your code inserts a FriendDecl into
the reverse-friends list of whatever declaration is associated with the friend declaration.
For friend classes, this will be whatever decl was active in scope at the time (or
the decl introduced by the elaborated-type-specifier if none was around).  For friend
functions, it'll always be the "target declaration" of the friend declaration itself.
The access-control code works with the canonical declaration, so your code works
only as long as that's the one you push the friend into the reverse-friends chain of.

Try
  void foo(); // canonical decl
  ...
    friend void foo(); // separate decl
  ...
  (access here)
or
  class A; // canonical decl
  class A; // decl found by friend lookup
  ...
    friend class A;
  ...
  (access here)
or
    friend class A;
  ...
  class A {}; // this retroactively becomes the canonical decl
  ...
  (access here)

Anyway, if you're dealing with this issue, I didn't see it.

John.



More information about the cfe-dev mailing list