From patchwork Thu Oct 21 20:26:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 46509 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 277823857C7F for ; Thu, 21 Oct 2021 20:27:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 277823857C7F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1634848045; bh=FF2WARrvadXfFk5PLPUEDNZdObCtb0EXRuFRE7RNvaw=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=E4UA81MvqTEgp4b4gNhaOs6BO8xqyHmqg4tsC9gvkRO5Wyc74gadhlr4DK0+ZK0YO n1Ok90lr5s3lmrXdE+gU7C9p/HZh7Ys6d46Ccf/kVkHGT5iqQ7VzIyBU6E/QJivkm9 NW7wAdw/EAUTpjSO20CT3DtI3xvZ7xup2JoAseYg= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by sourceware.org (Postfix) with ESMTPS id 00B1B3858416 for ; Thu, 21 Oct 2021 20:26:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 00B1B3858416 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-581-UDHx4eMIN32fBBO3hx0m5A-1; Thu, 21 Oct 2021 16:26:17 -0400 X-MC-Unique: UDHx4eMIN32fBBO3hx0m5A-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 1D14C100CCC0 for ; Thu, 21 Oct 2021 20:26:16 +0000 (UTC) Received: from pdp-11.redhat.com (unknown [10.22.35.117]) by smtp.corp.redhat.com (Postfix) with ESMTP id A40CD19D9F; Thu, 21 Oct 2021 20:26:15 +0000 (UTC) To: Jason Merrill , GCC Patches Subject: [PATCH] c++: P2360R0: Extend init-stmt to allow alias-decl [PR102617] Date: Thu, 21 Oct 2021 16:26:10 -0400 Message-Id: <20211021202610.298481-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-14.0 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_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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-Patchwork-Original-From: Marek Polacek via Gcc-patches From: Marek Polacek Reply-To: Marek Polacek Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" The following patch implements C++23 P2360R0. This proposal merely extends init-statement to contain alias-declaration. init-statement is used in if/for/switch. The unsightly duplication of the new code seems to be necessary to handle for ( init-statement condition[opt] ; expression[opt] ) statement as well as for ( init-statement[opt] for-range-declaration : for-range-initializer ) statement Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? PR c++/102617 gcc/cp/ChangeLog: * parser.c (cp_parser_init_statement): Allow alias-declaration in init-statement. gcc/testsuite/ChangeLog: * g++.dg/cpp23/init-stmt1.C: New test. * g++.dg/cpp23/init-stmt2.C: New test. --- gcc/cp/parser.c | 52 +++++++++++++++++++------ gcc/testsuite/g++.dg/cpp23/init-stmt1.C | 31 +++++++++++++++ gcc/testsuite/g++.dg/cpp23/init-stmt2.C | 25 ++++++++++++ 3 files changed, 96 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp23/init-stmt1.C create mode 100644 gcc/testsuite/g++.dg/cpp23/init-stmt2.C base-commit: 1373066a46d8d47abd97e46a005aef3b3dbfe94a diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 49d951cfb19..8ba5370740e 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -12040,6 +12040,7 @@ cp_parser_handle_directive_omp_attributes (cp_parser *parser, tree *pattrs, init-statement: expression-statement simple-declaration + alias-declaration TM Extension: @@ -13987,12 +13988,13 @@ cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep, return statement; } -/* Parse a init-statement or the declarator of a range-based-for. +/* Parse an init-statement or the declarator of a range-based-for. Returns true if a range-based-for declaration is seen. init-statement: expression-statement - simple-declaration */ + simple-declaration + alias-declaration */ static bool cp_parser_init_statement (cp_parser *parser, tree *decl) @@ -14013,11 +14015,24 @@ cp_parser_init_statement (cp_parser *parser, tree *decl) { tree dummy; cp_parser_parse_tentatively (parser); - /* Parse the declaration. */ - cp_parser_simple_declaration (parser, - /*function_definition_allowed_p=*/false, - &dummy); - cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING)) + { + cp_parser_alias_declaration (parser); + if (cxx_dialect < cxx23 + && !cp_parser_uncommitted_to_tentative_parse_p (parser)) + pedwarn (cp_lexer_peek_token (parser->lexer)->location, + OPT_Wc__23_extensions, + "alias-declaration in init-statement only " + "available with %<-std=c++23%> or %<-std=gnu++23%>"); + } + else + { + /* Parse the declaration. */ + cp_parser_simple_declaration (parser, + /*function_definition_allowed_p=*/ + false, &dummy); + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); + } if (!cp_parser_parse_definitely (parser)) /* That didn't work, try to parse it as an expression-statement. */ cp_parser_expression_statement (parser, NULL_TREE); @@ -14038,10 +14053,23 @@ cp_parser_init_statement (cp_parser *parser, tree *decl) /* We're going to speculatively look for a declaration, falling back to an expression, if necessary. */ cp_parser_parse_tentatively (parser); - /* Parse the declaration. */ - cp_parser_simple_declaration (parser, - /*function_definition_allowed_p=*/false, - decl); + bool expect_semicolon_p = true; + if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING)) + { + cp_parser_alias_declaration (parser); + expect_semicolon_p = false; + if (cxx_dialect < cxx23 + && !cp_parser_uncommitted_to_tentative_parse_p (parser)) + pedwarn (cp_lexer_peek_token (parser->lexer)->location, + OPT_Wc__23_extensions, + "alias-declaration in init-statement only " + "available with %<-std=c++23%> or %<-std=gnu++23%>"); + } + else + /* Parse the declaration. */ + cp_parser_simple_declaration (parser, + /*function_definition_allowed_p=*/false, + decl); parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)) { @@ -14054,7 +14082,7 @@ cp_parser_init_statement (cp_parser *parser, tree *decl) "range-based % loops only available with " "%<-std=c++11%> or %<-std=gnu++11%>"); } - else + else if (expect_semicolon_p) /* The ';' is not consumed yet because we told cp_parser_simple_declaration not to. */ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); diff --git a/gcc/testsuite/g++.dg/cpp23/init-stmt1.C b/gcc/testsuite/g++.dg/cpp23/init-stmt1.C new file mode 100644 index 00000000000..29e3256aae6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/init-stmt1.C @@ -0,0 +1,31 @@ +// PR c++/102617 +// P2360R0: Extend init-statement to allow alias-declaration +// { dg-do compile { target c++20 } } +// Test valid use. + +int v[10]; + +void +g () +{ + for (using T = int; (T) false;) // { dg-error "only available with" "" { target c++20_only } } + ; + for (using T = int; T e : v) // { dg-error "only available with" "" { target c++20_only } } + (void) e; + if (using T = int; true) // { dg-error "only available with" "" { target c++20_only } } + { + T x = 0; + (void) x; + } + if constexpr (using T = int; true) // { dg-error "only available with" "" { target c++20_only } } + { + T x = 0; + (void) x; + } + switch (using T = int; 42) // { dg-error "only available with" "" { target c++20_only } } + case 42: + { + T x = 0; + (void) x; + } +} diff --git a/gcc/testsuite/g++.dg/cpp23/init-stmt2.C b/gcc/testsuite/g++.dg/cpp23/init-stmt2.C new file mode 100644 index 00000000000..ca6201bc340 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp23/init-stmt2.C @@ -0,0 +1,25 @@ +// PR c++/102617 +// P2360R0: Extend init-statement to allow alias-declaration +// { dg-do compile { target c++23 } } +// Test invalid use. + +int v[10]; +namespace N { using X = int; } + +void +g () +{ + for (using N::X; false;) // { dg-error "expected" } + ; + for (using N::X; int e : v) // { dg-error "expected" } + (void) e; + for (using T = int; using U = int; int e : v) // { dg-error "" } + ; + if (using N::X; false) // { dg-error "expected" } + {} + switch (using N::X; 0) // { dg-error "expected" } + ; + if (using T = int;) // { dg-error "expected" } + { + } +}