On Wed, Jan 30, 2019 at 01:39:11PM -0500, Jason Merrill wrote:
> On 1/28/19 9:46 PM, Marek Polacek wrote:
> > This patch fixes an ICE-on-invalid (becase out-of-line constructors can't 
> > have
> > template arguments and also because function templates can't be partially
> > specialized) in C++2a: when we're parsing
> > 
> >    template<typename T> template<typename U> A<T>::A<U> ()
> > 
> > in the attached test we end up parsing "A<T>::A<U>" as a type name, and 
> > first we
> > try a class-name.  First we process "A<T>::" as the nested name specifier 
> > and then
> > we parse "A<U>".  In this test that results in a BASELINK.  Because in this 
> > context
> > we're supposed to treat it as a typename ([temp.res]/6), we call 
> > make_typename_type,
> > but that crashes.
> 
> Hmm.  If we've done an actual lookup (that gave us a BASELINK), we aren't
> dealing with a member of an unknown specialization anymore, so we should
> just use the result of the lookup rather than speculate about what the name
> might mean.  Why are we still trying to treat it as a typename?

Good point.  It's because cp_parser_class_name has:

23095   /* Any name names a type if we're following the `typename' keyword
23096      in a qualified name where the enclosing scope is type-dependent.  */
23097   typename_p = (typename_keyword_p && scope && TYPE_P (scope)
23098                 && dependent_type_p (scope));

and scope is in this case "A<T>" which is dependent.  Then there's this
"identifier, but not template-id" case which only performs name lookup when
typename_p is false.  But we're parsing "A<U>" so we call
cp_parser_template_id.  It sees CPP_TEMPLATE_ID -- an already parsed
template-id, so it just returns it, which is a BASELINK.  So even messing
with tag_type wouldn't help.

Does this answer your question?

Marek

Reply via email to