aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2020-10-19 18:13:42 -0400
committerMarek Polacek <polacek@redhat.com>2020-10-28 15:25:51 -0400
commit323dd4255203479d8c456b85513db4f8e0041d04 (patch)
tree97ae87500e1c9b433833060be3b20272e028ff4c /gcc/cp/parser.c
parent43cb72263fb3b7b97a74fb38d71364a1d5cf0448 (diff)
downloadgcc-323dd4255203479d8c456b85513db4f8e0041d04.zip
gcc-323dd4255203479d8c456b85513db4f8e0041d04.tar.gz
gcc-323dd4255203479d8c456b85513db4f8e0041d04.tar.bz2
c++: Member template function lookup failure [PR94799]
My earlier patch for this PR, r11-86, broke pybind11. That patch changed cp_parser_class_name to also consider the object expression scope (parser->context->object_type) to fix parsing of p->template A<T>::foo(); // consider p's scope too Here we reject b.operator typename B<T>::type(); because 'typename_p' in cp_parser_class_name uses 'scope', which means that 'typename_p' will be true for the example above. Then we create a TYPENAME_TYPE via make_typename_type, which fails when tsubsting it; the code basically created 'typename B::B' and then we complain that there is no member named 'B' in 'A<int>'. So, when deciding if we should create a TYPENAME_TYPE, don't consider the object_type scope, like we did pre-r11-86. gcc/cp/ChangeLog: PR c++/94799 * parser.c (cp_parser_class_name): Use parser->scope when setting typename_p. gcc/testsuite/ChangeLog: PR c++/94799 * g++.dg/template/lookup16.C: New test.
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 80d903c..2340795 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -23794,13 +23794,10 @@ cp_parser_class_name (cp_parser *parser,
bool enum_ok)
{
tree decl;
- tree scope;
- bool typename_p;
- cp_token *token;
tree identifier = NULL_TREE;
/* All class-names start with an identifier. */
- token = cp_lexer_peek_token (parser->lexer);
+ cp_token *token = cp_lexer_peek_token (parser->lexer);
if (token->type != CPP_NAME && token->type != CPP_TEMPLATE_ID)
{
cp_parser_error (parser, "expected class-name");
@@ -23816,14 +23813,16 @@ cp_parser_class_name (cp_parser *parser,
where we first want to look up A<T>::a in the class of the object
expression, as per [basic.lookup.classref]. */
- scope = parser->scope ? parser->scope : parser->context->object_type;
+ tree scope = parser->scope ? parser->scope : parser->context->object_type;
if (scope == error_mark_node)
return error_mark_node;
/* Any name names a type if we're following the `typename' keyword
in a qualified name where the enclosing scope is type-dependent. */
- typename_p = (typename_keyword_p && scope && TYPE_P (scope)
- && dependent_type_p (scope));
+ const bool typename_p = (typename_keyword_p
+ && parser->scope
+ && TYPE_P (parser->scope)
+ && dependent_type_p (parser->scope));
/* Handle the common case (an identifier, but not a template-id)
efficiently. */
if (token->type == CPP_NAME