From patchwork Fri Dec 7 13:33:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Dodji Seketeli X-Patchwork-Id: 204488 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 13F6D2C00C4 for ; Sat, 8 Dec 2012 00:34:31 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1355492072; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:From:To:Cc:Subject:References:Date:In-Reply-To: Message-ID:User-Agent:MIME-Version:Content-Type: Content-Transfer-Encoding:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=3w8NFmcJWT1KIzn6Ga/4dMcIooM=; b=TWccczQgcPxXRYL /X5F4Yu0z2iXh8wz7Zj1emJx4r7XI04lxG3WS/Xgvda3oTwwGpcP2Ar5JZaAVgAV jm8wi1mEQJdTMCVylpOVGGNrTgJnku6Rczwn5cA7Fl89bT1mknQ5+bkyuZY8klBb TWYgeZnB4TIkUw7q+wjLd82y5sRM= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:From:To:Cc:Subject:References:X-URL:Date:In-Reply-To:Message-ID:User-Agent:MIME-Version:Content-Type:Content-Transfer-Encoding:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=D26uaAPA6GSmAXbABClwRdJwO3L5IZ92YIvo7vXGvLEdn84dvvb/4zNCaaDT+w FDOBcS+87QCwta1o/MzjE/33lCkbAnD7PjSA9nMpnr84ASQez8hyx3AZwc7ANbRS TMub/qioSj65ZMJDdkGIwXRA9aRVlhL/ccRk8a7FMz45g=; Received: (qmail 7737 invoked by alias); 7 Dec 2012 13:34:17 -0000 Received: (qmail 7487 invoked by uid 22791); 7 Dec 2012 13:34:15 -0000 X-SWARE-Spam-Status: No, hits=-6.0 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 07 Dec 2012 13:34:01 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qB7DY03h022902 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 7 Dec 2012 08:34:00 -0500 Received: from localhost (ovpn-116-90.ams2.redhat.com [10.36.116.90]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id qB7DXxYt010899 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 7 Dec 2012 08:34:00 -0500 Received: by localhost (Postfix, from userid 1000) id 6184C2C1DA8; Fri, 7 Dec 2012 14:33:57 +0100 (CET) From: Dodji Seketeli To: Jason Merrill Cc: Gabriel Dos Reis , GCC Patches Subject: Re: [PING] [PATCH] PR c++/54401 - Confusing diagnostics about type-alias at class scope References: <87626yupft.fsf@redhat.com> <874nkpvfk3.fsf@seketeli.org> <50A652F6.9000804@redhat.com> <87ehjstfrx.fsf@seketeli.org> <50BE29C5.7060507@redhat.com> X-URL: http://www.redhat.com Date: Fri, 07 Dec 2012 14:33:56 +0100 In-Reply-To: <50BE29C5.7060507@redhat.com> (Jason Merrill's message of "Tue, 04 Dec 2012 11:50:13 -0500") Message-ID: <87zk1qasvv.fsf@redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux) MIME-Version: 1.0 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 Jason Merrill writes: > Oops, thought I had sent this before. No problem. Thank you for replying now× > On 11/17/2012 10:23 AM, Dodji Seketeli wrote: > > - if (cp_parser_parse_definitely (parser)) > > + /* Note that if we actually see the '=' token after the > > + identifier, cp_parser_alias_declaration commits the > > + tentative parse. In that case, we really expects an > > + alias-declaration. Otherwise, we expect a using > > + declaration. */ > > + alias_decl_expected = > > + !cp_parser_uncommitted_to_tentative_parse_p (parser); > > + cp_parser_parse_definitely (parser); > > Maybe just check whether decl is error_mark_node? As we further discussed this on IRC, when cp_parser_alias_declaration returns error_mark_node, it is either because we encountered an error before the hypothetical '=', in which case we might want to try to parse a using declaration, or it is because we encountered an error after the the '=', in which case we committed to parsing an alias declaration and we must emit a hard error. And I believe what we want here is to tell the two possible cases apart. > > > + if (type == error_mark_node) > > + return error_mark_node; > > I think for error-recovery we might want to > cp_parser_skip_to_end_of_block_or_statement as well. Right, done. Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk. gcc/cp/ * parser.c (cp_parser_alias_declaration): Commit to tentative parse when see the '=' token. Get out if the type-id is invalid. Update function comment. (cp_parser_member_declaration): Don't try to parse a using declaration if we know that we expected an alias declaration; that is, if we see the '=' token after the identifier. gcc/testsuite/ * g++.dg/cpp0x/alias-decl-28.C: New test. * g++.dg/cpp0x/alias-decl-16.C: Update. --- gcc/cp/parser.c | 31 +++++++++++++++++++++++++++--- gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C | 2 +- gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C | 7 +++++++ 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index a010f1f..c39ef30 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -15262,7 +15262,11 @@ cp_parser_using_declaration (cp_parser* parser, /* Parse an alias-declaration. alias-declaration: - using identifier attribute-specifier-seq [opt] = type-id */ + using identifier attribute-specifier-seq [opt] = type-id + + Note that if this function is used in the context of a tentative + parse, it commits the currently active tentative parse after it + sees the '=' token. */ static tree cp_parser_alias_declaration (cp_parser* parser) @@ -15295,6 +15299,8 @@ cp_parser_alias_declaration (cp_parser* parser) if (cp_parser_error_occurred (parser)) return error_mark_node; + cp_parser_commit_to_tentative_parse (parser); + /* Now we are going to parse the type-id of the declaration. */ /* @@ -15324,10 +15330,19 @@ cp_parser_alias_declaration (cp_parser* parser) if (parser->num_template_parameter_lists) parser->type_definition_forbidden_message = saved_message; + if (type == error_mark_node) + { + cp_parser_skip_to_end_of_block_or_statement (parser); + return error_mark_node; + } + cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); if (cp_parser_error_occurred (parser)) - return error_mark_node; + { + cp_parser_skip_to_end_of_block_or_statement (parser); + return error_mark_node; + } /* A typedef-name can also be introduced by an alias-declaration. The identifier following the using keyword becomes a typedef-name. It has @@ -19063,9 +19078,19 @@ cp_parser_member_declaration (cp_parser* parser) else { tree decl; + bool alias_decl_expected; cp_parser_parse_tentatively (parser); decl = cp_parser_alias_declaration (parser); - if (cp_parser_parse_definitely (parser)) + /* Note that if we actually see the '=' token after the + identifier, cp_parser_alias_declaration commits the + tentative parse. In that case, we really expects an + alias-declaration. Otherwise, we expect a using + declaration. */ + alias_decl_expected = + !cp_parser_uncommitted_to_tentative_parse_p (parser); + cp_parser_parse_definitely (parser); + + if (alias_decl_expected) finish_member_declaration (decl); else cp_parser_using_declaration (parser, diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C index d66660a..ce6ad0a 100644 --- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-16.C @@ -23,6 +23,6 @@ template using A3 = enum B3 {b = 0;}; //{ dg-error "types may not be defined in alias template" } -A3 a3; +A3 a3; // { dg-error "'A3' does not name a type" } int main() { } diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C new file mode 100644 index 0000000..086b5e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-28.C @@ -0,0 +1,7 @@ +// Origin: PR c++/54401 +// { dg-do compile { target c++11 } } + +template +struct X { + using type = T; // { dg-error "expected type-specifier|does not name a type" } +};