On Tue, Mar 20, 2018 at 6:07 PM, Alexandre Oliva <aol...@redhat.com> wrote: > On Mar 20, 2018, Jason Merrill <ja...@redhat.com> wrote: > >> On Fri, Mar 16, 2018 at 5:38 PM, Alexandre Oliva <aol...@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