This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PR c++/84789] do not resolve typename into template-independent
- From: Jason Merrill <jason at redhat dot com>
- To: Alexandre Oliva <aoliva at redhat dot com>
- Cc: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 20 Mar 2018 21:36:00 -0400
- Subject: Re: [PR c++/84789] do not resolve typename into template-independent
- References: <orpo43vgzj.fsf@lxoliva.fsfla.org> <CADzB+2=DKytZNuCk3DRw_VsAYp5Eck0xDs6XnEdJKqMLg0Gadw@mail.gmail.com> <orefkel7sz.fsf@lxoliva.fsfla.org>
On Tue, Mar 20, 2018 at 6:07 PM, Alexandre Oliva <aoliva@redhat.com> wrote:
> On Mar 20, 2018, Jason Merrill <jason@redhat.com> wrote:
>
>> On Fri, Mar 16, 2018 at 5:38 PM, Alexandre Oliva <aoliva@redhat.com> wrote:
>>> resolve_typename_type may peek into template types that might still be
>>> specialized. In some cases, e.g. g++.dg/template/friend48.C or
>>> g++.dg/template/decl2.C, that is exactly the right thing to do. In
>>> others, like the newly-added testcase g++.dg/template/pr84789.C, it
>>> isn't, and if the qualifying scope happens to resolve to a non-template
>>> type, we resolve to that and then fail the assert that checks we still
>>> have a template-dependent scope.
>
>> We're looking inside them because we're trying to parse a declarator;
>> the tentative parse will fail in this case, because we aren't in a
>> declarator, but that doesn't mean it's wrong to peek.
>
> Huh? We're referencing members of an unrelated template that AFAIK
> needs not even be defined at that point, and even if it is, it could
> still be specialized afterwards. How can it possibly be right to
> short-circuit such nested names? How would template
> instantiation/specialization get a chance to do the proper mapping?
>
> template<typename> struct B : A {}; // would /*: A {}*/ make any diff?
> template<typename T> struct C : B<T> // would /* : B<T>*/ make any diff?
> {
> B<T>::A::I::I i; // { dg-error "typename" }
> };
> Is it by any chance the fact that B<T> is a base class for C<T> that
> makes it correct to peek into it? I don't recall any exception of this
> sort.
No, we look inside when we're trying to parse the qualified-id as the
name of a declaration; in a declarator-id we can look into
uninstantiated classes, otherwise there would be no way to define
members of class templates.
void X<T>::N::f() { } // looks inside X<T>
>> I disagree; it seems to me that the assert should allow the case where
>> the scope was originally dependent, but got resolved earlier in the
>> function.
>
> Doesn't the function always take dependent scopes? I for some reason
> thought that was the case.
Yes, as the comment says, a TYPENAME_TYPE should always have a
dependent scope. In this case, the dependent scope was "typename
B<T>::A", but just above we resolved it to just A, making it no longer
dependent.
Jason