[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