This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

Re: [PR c++/84789] do not resolve typename into template-independent


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


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