From patchwork Wed Mar 13 17:25:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1056174 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-497836-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="XTyGUO0h"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44KJdt5WLTz9s4V for ; Thu, 14 Mar 2019 04:25:51 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=MvRbH1fH7aXAJmbUhi1Bbjq+F3XMNgLeH4+0V8qbVPzIzcTxIiglp F/9+tQIwtIO78iLse0MI0n3WPtC7kk+80QuNGFv7tkoCwume5z5bGn2cKIJe5Z7h 6FNuWW2RrcHcCoOUmBdo2+4DacOwpPqKBw5HKf2a3sSAqHn/tZEMpU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=ogpepGVCcFkOVxaH3FVmJKpu+k0=; b=XTyGUO0hyoQWT2YIuio1 Ahv+xt3G1xhT8Y7WzxZBhQWNeN7WP4iA+6cGjzPW02JhfghTqMtZd65a7gI18hyn IGBztQBroMzJR+kcukVDRX0VMdJj+3QtREdnDle4qX7veRRbTmDU6tVAC8Uyldl0 nnhc8xGQuZ5Yg6EYnkGsXFU= Received: (qmail 65187 invoked by alias); 13 Mar 2019 17:25:43 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 65175 invoked by uid 89); 13 Mar 2019 17:25:43 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.1 spammy=FLAGS, sk:maybe_c, friend, our X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 13 Mar 2019 17:25:42 +0000 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 mx1.redhat.com (Postfix) with ESMTPS id 2F441C0AC343 for ; Wed, 13 Mar 2019 17:25:41 +0000 (UTC) Received: from redhat.com (unknown [10.20.4.51]) by smtp.corp.redhat.com (Postfix) with ESMTPS id CCCF360F89; Wed, 13 Mar 2019 17:25:40 +0000 (UTC) Date: Wed, 13 Mar 2019 13:25:39 -0400 From: Marek Polacek To: GCC Patches , Jason Merrill Subject: C++ PATCH for c++/88979 - further P0634 fix for constructors Message-ID: <20190313172539.GR26967@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.11.3 (2019-02-01) This PR points out that our P0634 implementation misses constructor parameters and still requires 'typename'. I'm not 100% sure if the standard really says we should also handle constructors. Does a constructor have a function type? But I guess it makes sense, so this patch handles it. To handle a constructor in a class, we need to pass flags to cp_parser_constructor_declarator_p. To handle an out-of-line constructor, use constructor_name_p. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2019-03-13 Marek Polacek PR c++/88979 - further P0634 fix for constructors. * parser.c (cp_parser_decl_specifier_seq): Pass flags to cp_parser_constructor_declarator_p. (cp_parser_direct_declarator): Allow missing typename for constructor parameters. (cp_parser_constructor_declarator_p): Add FLAGS parameter. Pass it to cp_parser_type_specifier. * g++.dg/cpp2a/typename15.C: New test. diff --git gcc/cp/parser.c gcc/cp/parser.c index f95111169ed..8244366e669 100644 --- gcc/cp/parser.c +++ gcc/cp/parser.c @@ -2506,7 +2506,7 @@ static cp_expr cp_parser_simple_cast_expression static tree cp_parser_global_scope_opt (cp_parser *, bool); static bool cp_parser_constructor_declarator_p - (cp_parser *, bool); + (cp_parser *, cp_parser_flags, bool); static tree cp_parser_function_definition_from_specifiers_and_declarator (cp_parser *, cp_decl_specifier_seq *, tree, const cp_declarator *); static tree cp_parser_function_definition_after_declarator @@ -14052,7 +14052,8 @@ cp_parser_decl_specifier_seq (cp_parser* parser, = (!found_decl_spec && constructor_possible_p && (cp_parser_constructor_declarator_p - (parser, decl_spec_seq_has_spec_p (decl_specs, ds_friend)))); + (parser, flags, decl_spec_seq_has_spec_p (decl_specs, + ds_friend)))); /* If we don't have a DECL_SPEC yet, then we must be looking at a type-specifier. */ @@ -21160,7 +21161,13 @@ cp_parser_direct_declarator (cp_parser* parser, tree decl = cp_parser_lookup_name_simple (parser, unqualified_name, token->location); - if (!is_overloaded_fn (decl)) + if (!is_overloaded_fn (decl) + /* Allow + template + A::A(T::type) { } */ + && !(MAYBE_CLASS_TYPE_P (qualifying_scope) + && constructor_name_p (unqualified_name, + qualifying_scope))) flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL; } } @@ -27380,10 +27387,12 @@ cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p) /* Returns TRUE if the upcoming token sequence is the start of a constructor declarator or C++17 deduction guide. If FRIEND_P is true, the - declarator is preceded by the `friend' specifier. */ + declarator is preceded by the `friend' specifier. The parser flags FLAGS + is used to control type-specifier parsing. */ static bool -cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) +cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags, + bool friend_p) { bool constructor_p; bool outside_class_specifier_p; @@ -27562,9 +27571,10 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) = parser->num_template_parameter_lists; parser->num_template_parameter_lists = 0; - /* Look for the type-specifier. */ + /* Look for the type-specifier. It's not optional, but its typename + might be. */ cp_parser_type_specifier (parser, - CP_PARSER_FLAGS_NONE, + (flags & ~CP_PARSER_FLAGS_OPTIONAL), /*decl_specs=*/NULL, /*is_declarator=*/true, /*declares_class_or_enum=*/NULL, diff --git gcc/testsuite/g++.dg/cpp2a/typename15.C gcc/testsuite/g++.dg/cpp2a/typename15.C new file mode 100644 index 00000000000..9094190cec9 --- /dev/null +++ gcc/testsuite/g++.dg/cpp2a/typename15.C @@ -0,0 +1,15 @@ +// PR c++/88979 +// { dg-do compile { target c++2a } } + +template +struct B { + B(T::type); +}; + +template +struct A { + A(T::type); +}; + +template +A::A(T::type) { }