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