This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Internal error, RHv6.0 i386 gcc v2.95.2


> Are you sure it's fixed?  Unless I'm mistaken, line 386 is merely
> declaring a friend template class, not specializing the class.

I'm not sure whether it is fixed; I'm having difficulties interpreting
the standard here. My current interpretation is that this is
ill-formed for syntactical reasons; the error message of g++ might be
misleading, though.

Your simplified example is a big help, let's study this instead. I
take this really slow, with bullet items so you can skip elaborations
you agree to.

> namespace one {
>     template <class T>
>     class A {};
> };
> 
> namespace two {
>     class B {
>         template <class T>
>         friend class one::A<T>;
>     };
> };
> 
> int main(int argc, char** argv)
> {
>     two::B b;
> }

Looking at 

  template <class T> friend class one::A<T>;

I ask: What kind of declaration is this? 14.5.3, [temp.friend]/1 says

# A friend of a class or class template can be a function template or
# class template, a specialization of a function template or class
# template, or an ordinary (nontemplate) function or class.

A. So your claim is that the friend is the class template, not a
   specialization.

   Let's assume for a moment that this does not refer to a class
   template. 14.5.3/1 then goes on

   # For a friend function declaration that is not a template
   # declaration:

   # if the name of the friend is a qualified or unqualified
   # template­id, the friend declaration refers to a specialization of
   # a function template, otherwise

   I guess the 'name of the friend' here is 'one::A<T>', so *it is* a
   qualified template-id. So it should be a specialization of a
   function template? How can I declare class template specializations
   as friends, then? Perhaps the 'name of the friend' is 'class
   one::A<T>'? Let's go on and assume that this does not apply

   # if the name of the friend is a qualified­id and a matching
   # nontemplate function is found in the specified class or
   # namespace, the friend declaration refers to that function,
   # otherwise,

   No, we did not find a matching function

   # if the name of the friend is a qualified­id and a matching
   # specialization of a template function is found in the specified
   # class or namespace, the friend declaration refers to that
   # function specialization, otherwise,

   No, we did not find a matching specialization, either

   # the name shall be an unqualified­id that declares (or redeclares)
   # an ordinary (nontemplate) function.

   No, the name is not an unqualified-id. So the code is in error, it
   would appear. Interestingly, it does not allow for specializations
   being friends, which are then given in the example:

   #    friend class task<int>;

B. Since we want the template to be the friend, apparently we must put
   a template declaration into the friend declaration. However, this
   is not the syntax of a template declaration.

   14.5, [temp.decls]/1 specifies

   # A template­id, that is, the template­name followed by a
   # template­argument­list shall not be specified in the declaration
   # of a primary template declaration.

   This does not explicitly mention a friend declaration, but an
   (non-normative) note explains what the exceptions are

   # [Note: however, this syntax is allowed in class template partial
   # specializations (14.5.4). ]

   Since this is not what we want to do, it seems that we must not put
   the template-id in the friend declaration.

C. After correcting the example as

namespace one {
    template <class T>
    class A {};
};

namespace two {
    class B {
        template <class T>
        friend class one::A;
    };
};

int main(int argc, char** argv)
{
    two::B b;
}

g++ accepts it just fine.

Without checking, it seems that g++ sees a qualified template
id. Looking at above rules, it knows that this must be a
specialization, and then finds several problems in that assumption.

If you question this line of reasoning, I'd prefer if you discuss it
in one of the public C++ fora first, eg. comp.lang.c++.moderated, or
comp.std.c++. However, if you can tell me right-away where I erred,
I'd be happy to be corrected.

Regards,
Martin

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]