From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTP id 596F53973091 for ; Tue, 20 Oct 2020 00:52:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 596F53973091 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-591-hdhzdXg5NEigBCbKjCwYbg-1; Mon, 19 Oct 2020 20:52:13 -0400 X-MC-Unique: hdhzdXg5NEigBCbKjCwYbg-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 20E6A10E2183 for ; Tue, 20 Oct 2020 00:52:12 +0000 (UTC) Received: from pdp-11.redhat.com (ovpn-113-143.rdu2.redhat.com [10.10.113.143]) by smtp.corp.redhat.com (Postfix) with ESMTP id B511560C13; Tue, 20 Oct 2020 00:52:11 +0000 (UTC) From: Marek Polacek To: Jason Merrill , GCC Patches Subject: [PATCH] c++: Member template function lookup failure [PR94799] Date: Mon, 19 Oct 2020 20:52:02 -0400 Message-Id: <20201020005202.64863-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="US-ASCII" X-Spam-Status: No, score=-14.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Oct 2020 00:52:17 -0000 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::foo(); // consider p's scope too Here we reject b.operator typename B::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'. So, when deciding if we should create a TYPENAME_TYPE, don't consider the object_type scope, like we did pre-r11-86. Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? 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. --- gcc/cp/parser.c | 13 ++++++------- gcc/testsuite/g++.dg/template/lookup16.C | 23 +++++++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/lookup16.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7ec7d42773c..ecbd4b7d15a 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -23784,13 +23784,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"); @@ -23806,14 +23803,16 @@ cp_parser_class_name (cp_parser *parser, where we first want to look up A::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 diff --git a/gcc/testsuite/g++.dg/template/lookup16.C b/gcc/testsuite/g++.dg/template/lookup16.C new file mode 100644 index 00000000000..5b34c08282c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/lookup16.C @@ -0,0 +1,23 @@ +// PR c++/94799 +// { dg-do compile { target c++11 } } + +template struct A { + typedef int type; + operator int(); +}; + +template using B = A; + +template typename B::type foo(B b) +{ + auto r1 = b.operator typename A::type(); + auto r2 = b.operator typename A::template A::type(); + auto r3 = b.operator typename B::type(); + auto r4 = b.operator typename B::template A::type(); + return r1 + r2 + r3 + r4; +} + +void bar() +{ + foo(A()); +} base-commit: 970d683f67777319990b30302a21a860990e2ec8 -- 2.26.2