This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH for 3.1] Fix PR6716 regression (take 4)
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 02 Jul 2002 22:32:31 +0700
- Subject: Re: [C++ PATCH for 3.1] Fix PR6716 regression (take 4)
- References: <3D1DC9D8.3F1C3E0E@users.sourceforge.net> <51160000.1025541509@gandalf.codesourcery.com>
- Reply-to: lerdsuwa at users dot sourceforge dot net
Mark Mitchell wrote:
>
> > template<class T> void f(typename C<T>::X &); //#1
> > template<class T> struct C {
> > class X {
> > friend void f(typename C<T>::X &); //#2
> > ...
> > };
> > X x;
> > ...
> > };
> >
> > When instantiating X inside C<int>, we process the friend function #2.
> > There we have to do name lookup for typename C<T>::X (with T=int) at #1
> > to decide whether #1 is right the function #2 actually refers to.
> > So all field of C<int> have to be set up before we try to complete
> > its field x.
> >
> > The logic to decide if the field can be added to TYPE_FIELDS is in
> > the new function, can_complete_type. We detect invalid field by
> > looking for TYPE_BEING_DEFINED != 0.
>
> I think this version is much closer, but it still doesn't seem right to
> me.
>
> Whether or not #1 and #2 are the same function has nothing to do with
> the data member "x". (It doesn't even had to do with the type 'X';
> the use of "typename" guarantees that those two functions have the
> same type.) So, I'm confused as to why you have to do the more
> complicated thing that you did.
That's because inside class C<T>::X the typename #2 is simplified to
just X. The logic is there in make_typename_type. So we don't see
TYPENAME_TYPE node, but a RECORD_TYPE. But for #1, we need to deduce
T (sorry, the code example should look like below, it's simplified
from g++.dg/template/friend.C)
friend void f<T>(typename C<T>::X &); //#2
Then substitute T into 'typename C<T>::X' and compare the two RECORD_TYPE's.
> Also, can_complete_type is at best misnamed. Clearly, there are some
> types that cannot be completed but which are accepted by your function.
> For example, a class type that has no definition will be treated as
> "can_complete_type". If we really need to do this, the function should
> go in pt.c and it should be named "can_complete_type_without_circularity"
> or some such. Also, since the particular type returned isn't used, why
> not just return a boolean?
>
> I think we've beaten on this about as much as we can at this point. If
> you make the changes suggested above for can_complete_type (put it pt.c,
> make it static, rename it, change the return type), then the patch is
> OK, even though I'm not quite comfortable with it. It does fix an
> important problem.
I am making the suggested modification and checking the patch in.
I'll post the patch in a separate message.
--Kriang