From patchwork Tue Apr 7 19:53:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 1267618 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=dewVCTHa; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48xdQg5M3pz9sP7 for ; Wed, 8 Apr 2020 05:54:19 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 09B74388700B; Tue, 7 Apr 2020 19:54:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 09B74388700B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1586289257; bh=+rj8y6X4f1XCuSiaWMYuZNiMAmNFqDvP6fqpOAtxIUc=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=dewVCTHahePkPUMOmw/uCQjpxX+BOjpwraJ5PpZLFOjkrdwYWn+4yV2r1/rhvyFzA tgTQxwZLiWOLbt3XR/IQyKsv163ngoMRFmFLYXkr22K2x/6M2BcD6OfzxYumGk93em CsXJ/MHP4qgASaOdypliZOQq39yPtJ0EouPU5V/E= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [207.211.31.81]) by sourceware.org (Postfix) with ESMTP id 14A183877034 for ; Tue, 7 Apr 2020 19:54:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 14A183877034 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-305-iaJxk0pzPs2Ku2xBMYqxPg-1; Tue, 07 Apr 2020 15:53:38 -0400 X-MC-Unique: iaJxk0pzPs2Ku2xBMYqxPg-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 A8CA3DB22 for ; Tue, 7 Apr 2020 19:53:37 +0000 (UTC) Received: from tucnak.zalov.cz (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8F7CC60BFB for ; Tue, 7 Apr 2020 19:53:36 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id 037JrYLW010947 for ; Tue, 7 Apr 2020 21:53:34 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id 037JrX5R010946 for gcc-patches@gcc.gnu.org; Tue, 7 Apr 2020 21:53:33 +0200 Date: Tue, 7 Apr 2020 21:53:33 +0200 To: gcc-patches@gcc.gnu.org Subject: Backports to 9.4 Message-ID: <20200407195333.GE2212@tucnak> MIME-Version: 1.0 User-Agent: Mutt/1.11.3 (2019-02-01) X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-24.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LOTSOFHASH, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_DNSWL_NONE, SCC_10_SHORT_WORD_LINES, SCC_20_SHORT_WORD_LINES, SCC_5_SHORT_WORD_LINES, 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-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: "Li, Pan2 via Gcc-patches" Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi! I've backported following 21 commits from trunk to 9.4, bootstrapped/regtested on x86_64-linux and i686-linux and committed to 9 branch. Jakub From 980a7a0be5a114e285c49ab05ac70881e4f27fc3 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 17 Mar 2020 21:21:16 +0100 Subject: [PATCH] c++: Fix parsing of invalid enum specifiers [PR90995] The testcase shows some accepts-invalid (the ones without alignas) and ice-on-invalid-code (the ones with alignas) cases. If the enum doesn't have an underlying type and is not a definition, the caller retries to parse it as elaborated type specifier. E.g. for enum struct S s it will then pedwarn that elaborated type specifier shouldn't have the struct/class keywords. The problem is if the enum specifier is not followed by { when it has underlying type. In that case we have already called cp_parser_parse_definitely to end the tentative parsing started at the beginning of cp_parser_enum_specifier. But the cp_parser_error (parser, "expected %<;%> or %<{%>"); doesn't emit any error because the whole function is called from yet another tentative parse and the caller starts parsing the elaborated type specifier where the cp_parser_enum_specifier stopped (i.e. after the underlying type token(s)). The ultimate caller than commits the tentative parsing (and even if it wouldn't, it wouldn't know what kind of error to report). I think after seeing enum {,struct,class} : type not being followed by { or ;, there is no reason not to report it right away, as it can't be valid C++, which is what the patch does. Not sure if we shouldn't also return error_mark_node instead of NULL_TREE, so that the caller doesn't try to parse it as elaborated type specifier (the patch doesn't do that right now). Furthermore, while reading the code, I've noticed that parser->colon_corrects_to_scope_p is saved and set to false at the start of the function, but not restored back in some cases. Don't have a testcase where this would be a problem, but it just seems wrong. Either we can in the two spots replace return NULL_TREE; with { type = NULL_TREE; goto out; } or we could perhaps abuse warning_sentinel or create a special class with dtor to clean the flag up. And lastly, I've fixed some formatting issues in the function while reading it. 2020-03-17 Jakub Jelinek PR c++/90995 * parser.c (cp_parser_enum_specifier): Use temp_override for parser->colon_corrects_to_scope_p, replace goto out with return. If scoped enum or enum with underlying type is not followed by { or ;, call cp_parser_commit_to_tentative_parse before calling cp_parser_error and make sure to return error_mark_node instead of NULL_TREE. Formatting fixes. * g++.dg/cpp0x/enum40.C: New test. --- gcc/cp/ChangeLog | 13 ++++++++ gcc/cp/parser.c | 52 ++++++++++++----------------- gcc/testsuite/ChangeLog | 8 +++++ gcc/testsuite/g++.dg/cpp0x/enum40.C | 26 +++++++++++++++ 4 files changed, 68 insertions(+), 31 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/enum40.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2e247069b96..8afe6aca339 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2020-04-07 Jakub Jelinek + + Backported from mainline + 2020-03-17 Jakub Jelinek + + PR c++/90995 + * parser.c (cp_parser_enum_specifier): Use temp_override for + parser->colon_corrects_to_scope_p, replace goto out with return. + If scoped enum or enum with underlying type is not followed by + { or ;, call cp_parser_commit_to_tentative_parse before calling + cp_parser_error and make sure to return error_mark_node instead of + NULL_TREE. Formatting fixes. + 2020-04-05 Marek Polacek 2020-02-06 Marek Polacek diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index e1c02d7b718..0219920be8f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -18705,9 +18705,7 @@ cp_parser_enum_specifier (cp_parser* parser) bool is_unnamed = false; tree underlying_type = NULL_TREE; cp_token *type_start_token = NULL; - bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; - - parser->colon_corrects_to_scope_p = false; + temp_override cleanup (parser->colon_corrects_to_scope_p, false); /* Parse tentatively so that we can back up if we don't find a enum-specifier. */ @@ -18747,24 +18745,24 @@ cp_parser_enum_specifier (cp_parser* parser) push_deferring_access_checks (dk_no_check); nested_name_specifier - = cp_parser_nested_name_specifier_opt (parser, - /*typename_keyword_p=*/true, - /*check_dependency_p=*/false, - /*type_p=*/false, - /*is_declaration=*/false); + = cp_parser_nested_name_specifier_opt (parser, + /*typename_keyword_p=*/true, + /*check_dependency_p=*/false, + /*type_p=*/false, + /*is_declaration=*/false); if (nested_name_specifier) { tree name; identifier = cp_parser_identifier (parser); - name = cp_parser_lookup_name (parser, identifier, - enum_type, - /*is_template=*/false, - /*is_namespace=*/false, - /*check_dependency=*/true, - /*ambiguous_decls=*/NULL, - input_location); + name = cp_parser_lookup_name (parser, identifier, + enum_type, + /*is_template=*/false, + /*is_namespace=*/false, + /*check_dependency=*/true, + /*ambiguous_decls=*/NULL, + input_location); if (name && name != error_mark_node) { type = TREE_TYPE (name); @@ -18844,23 +18842,21 @@ cp_parser_enum_specifier (cp_parser* parser) { if (cxx_dialect < cxx11 || (!scoped_enum_p && !underlying_type)) { + if (has_underlying_type) + cp_parser_commit_to_tentative_parse (parser); cp_parser_error (parser, "expected %<{%>"); if (has_underlying_type) - { - type = NULL_TREE; - goto out; - } + return error_mark_node; } /* An opaque-enum-specifier must have a ';' here. */ if ((scoped_enum_p || underlying_type) && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) { + if (has_underlying_type) + cp_parser_commit_to_tentative_parse (parser); cp_parser_error (parser, "expected %<;%> or %<{%>"); if (has_underlying_type) - { - type = NULL_TREE; - goto out; - } + return error_mark_node; } } @@ -18876,9 +18872,7 @@ cp_parser_enum_specifier (cp_parser* parser) push_scope (nested_name_specifier); } else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL) - { - push_nested_namespace (nested_name_specifier); - } + push_nested_namespace (nested_name_specifier); } /* Issue an error message if type-definitions are forbidden here. */ @@ -19038,12 +19032,8 @@ cp_parser_enum_specifier (cp_parser* parser) pop_scope (nested_name_specifier); } else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL) - { - pop_nested_namespace (nested_name_specifier); - } + pop_nested_namespace (nested_name_specifier); } - out: - parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p; return type; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cf0d5d76f2d..c10d50b623b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2020-04-07 Jakub Jelinek + + Backported from mainline + 2020-03-17 Jakub Jelinek + + PR c++/90995 + * g++.dg/cpp0x/enum40.C: New test. + 2020-04-07 Jakub Jelinek PR target/94500 diff --git a/gcc/testsuite/g++.dg/cpp0x/enum40.C b/gcc/testsuite/g++.dg/cpp0x/enum40.C new file mode 100644 index 00000000000..cfdf2a4a18a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum40.C @@ -0,0 +1,26 @@ +// PR c++/90995 +// { dg-do compile { target c++11 } } + +void +foo () +{ + enum : int a alignas; // { dg-error "expected" } +} + +void +bar () +{ + enum : int a; // { dg-error "expected" } +} + +void +baz () +{ + enum class a : int b alignas; // { dg-error "expected" } +} + +void +qux () +{ + enum class a : int b; // { dg-error "expected" } +}