On Fri, Feb 01, 2019 at 12:02:44PM -0500, Jason Merrill wrote: > On 2/1/19 11:26 AM, Marek Polacek wrote: > > 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? > > Mostly, though I'm still curious how we got the previous parse of the > template-id and yet continued to try to parse it as a class-name.
So we have template<typename T> template<typename U> A<T>::A<U> () and we're in cp_parser_single_declaration. We're trying to parse the decl-specifier-seq, and that first tries to parse variou RID_* keywords and if that doesn't work it tries to parse a constructor: /* Constructors are a special case. The `S' in `S()' is not a decl-specifier; it is the beginning of the declarator. */ constructor_p = (!found_decl_spec && constructor_possible_p && (cp_parser_constructor_declarator_p (parser, decl_spec_seq_has_spec_p (decl_specs, ds_friend)))); cp_parser_constructor_declarator_p calls cp_parser_nested_name_specifier_opt and that's where we parse the two template-ids, A<T> and A<U>. But cp_parser_constructor_declarator_p isn't successful so we go to parsing A<T>::A<U> as a type-specifier, and that's where the above happens. > The patch is OK. Thanks. Marek