c++: Member template function lookup failure [PR94799]
Whew, this took a while. We fail to parse "p->template A<T>::a()"
(where p is of type A<T> *) because since r249752 we treat the RHS of the ->
as dependent and avoid a lookup in the enclosing context: since that rev
cp_parser_template_name checks parser->context->object_type too, which
here is unknown_type_node, signalling a type-dependent object:
7756 if (dependent_p)
7757 /* Tell cp_parser_lookup_name that there was an object, even though it's
7758 type-dependent. */
7759 parser->context->object_type = unknown_type_node;
with which cp_parser_template_name returns identifier 'A', cp_parser_class_name
then creates a TEMPLATE_ID_EXPR A<T>, but then
23735 decl = make_typename_type (scope, decl, tag_type, tf_error);
in cp_parser_class_name fails because scope is NULL. Then we return
error_mark_node and parse errors ensue.
I've tried various approaches, e.g. keeping TEMPLATE_ID_EXPR around
instead of calling make_typename_type, which didn't work, whereupon I
realized that since we don't want to perform name lookup if we've seen
the template keyword and the scope is dependent, we can adjust
parser->context->object_type and use the type of the object expression
as the scope, even if it's type-dependent. This should be in line with
[basic.lookup.classref]p4. If the postfix expression doesn't have a type,
use typeof to carry its type. This typeof will be processed in
tsubst/TYPENAME_TYPE.
PR c++/94799
* parser.c (cp_parser_postfix_dot_deref_expression): If we have
a type-dependent object of class type, stash it to
parser->context->object_type. If the postfix expression doesn't have
a type, use typeof.
(cp_parser_class_name): Consider object scope too.
(cp_parser_lookup_name): Remove code dealing with the case when
object_type is unknown_type_node.
* g++.dg/lookup/this1.C: Adjust dg-error.
* g++.dg/template/lookup12.C: New test.
* g++.dg/template/lookup13.C: New test.
* g++.dg/template/lookup14.C: New test.
* g++.dg/template/lookup15.C: New test.