[cfe-dev] [PATCH] Friend class cannot access protected field of parent
Olivier Goffart
ogoffart at kde.org
Tue Jun 8 14:18:13 PDT 2010
Le Tuesday 08 June 2010, John McCall a écrit :
> No, sorry, not without some more support. It's a hard question — at what
> point does an apparent drafting mistake in the standard become obligatory?
> — but I am comfortable with my current answer here.
ok
> I was offering some feedback since you said you'd done this as a way of
> getting into clang development.
Yes, thanks.
> Incidentally, even if we were going to support this, we would balk at
> adding an extra pointer of storage to every FunctionDecl (and to a lesser
> degree, to every CXXRecordDecl). A much more acceptable storage solution
> would be a side-table stored on the ASTContext.
>
> >>>> 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.
> >
> > I thought it is always the canonical one.
> > (line 479 and 586, I take the canonical form.)
> > Now, I'm new to clang code, so I might have forgot something.
>
> Ah, no, I missed that, sorry.
>
> We typically use assertions to document requirements like this.
>
> > This case does not work:
> >
> > class A;
> > class B : public A { friend class C; friend void foo();};
> > class A { protected: typedef int foo; };
> > class C { A::foo x; };
> >
> > It seems I do not support the fact it retroactively become the canonical
> > decl. I guess I can find the point where it becomes canonical, and move
> > the linked list to it. Do you have any pointer on where that happens?
I typed this code too fast. It is wrong because B need A to be declared.
So I got the canonical form right after all.
>
> During startDefinition.
>
> > (I'd also appreciate hints or suggestions for friend of template class
> > (the FIXME in the test))
>
> You'd need to make a reverse-friend list for ClassTemplateDecls (and
> FunctionTemplateDecls) and check whether the context class is associated
> with a template.
>
> Mostly, though, even if we were going to support this as a compatibility
> hack, I see no reason to extend it to friend templates in the absence of
> the evidence that anyone needs it.
Ok, thanks for your feedback.
--
Olivier
More information about the cfe-dev
mailing list