From patchwork Wed Oct 9 11:36:07 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 281835 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 209402C00C8 for ; Wed, 9 Oct 2013 22:36:27 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=IbayNpmqAowXDlxP8yS58ovVHIeNoqs6COz+/YCIttf wVc7FQ2aLW2Z86Xpd7zq9lagNuVkQQ0NfLAhku8ScRZn643duMuf+DdIvLxZcakg WwYRf2eQN5eqS5Wlfi/zx1xJwQg2tCtUfujU2AqfO8fFlwPU3opid3KxINr8wJJM = 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 :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=+SKKJ6d+mcPsif1UkzcLmUidCU8=; b=qm1gIZ6Hf8yEPfKQU +biHLpnnwzdXXxKLFpcIHzF1XBuQli4x5mKj2AKvqQaIduM/GZ+FRu3O7KLlO8Ul yhTDGaiWIwQlzpVxnKa4y3g36UhzNKZKSaD/9wLWuV8WmykFlEhWa7U37nfciFR2 RWDRNlARd80y/sadUUOajJa9Ng= Received: (qmail 7618 invoked by alias); 9 Oct 2013 11:36:17 -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 7609 invoked by uid 89); 9 Oct 2013 11:36:16 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-3.9 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_PASS, UNPARSEABLE_RELAY autolearn=ham version=3.3.2 X-HELO: aserp1040.oracle.com Received: from aserp1040.oracle.com (HELO aserp1040.oracle.com) (141.146.126.69) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Wed, 09 Oct 2013 11:36:15 +0000 Received: from ucsinet22.oracle.com (ucsinet22.oracle.com [156.151.31.94]) by aserp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r99BaCCA007550 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 9 Oct 2013 11:36:13 GMT Received: from userz7021.oracle.com (userz7021.oracle.com [156.151.31.85]) by ucsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r99BaBmI002445 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 9 Oct 2013 11:36:12 GMT Received: from abhmt101.oracle.com (abhmt101.oracle.com [141.146.116.53]) by userz7021.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r99BaBmx008944; Wed, 9 Oct 2013 11:36:11 GMT Received: from poldo4.casa (/79.53.235.35) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 09 Oct 2013 04:36:11 -0700 Message-ID: <52553FA7.6000906@oracle.com> Date: Wed, 09 Oct 2013 13:36:07 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.0 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: [C++ Patch] PR 58633 (Take 2) X-IsSubscribed: yes Hi, this is a completely different approach at fixing the bug, which overall I like better. In this case most of the patch touches cp_parser_decltype_expr: instead of using cp_parser_postfix_expression only for member access expressions, we accept all its valid return values (still identifying the member access expressions, of course, because the semantics of decltype is special for those). Thus we can also immediately accept the pseudo destructor calls which are the matter of this bug. Otherwise, as a last resort, if the expression at issue isn't a postfix expression at all, we use cp_parser_expression. Patch works better than my previous try from the diagnostic point of view (eg, for c++/47277 - type illegal expressions as arguments of the decltype) and seems less "hackish" to me. Also, it seems to me that it's a computational waste to redo the parsing of valid postfix-expressions != member access expression. Tested x86_64-linux. Thanks! Paolo. ///////////////////////// /cp 2013-10-09 Paolo Carlini PR c++/58633 * parser.c (cp_parser_decltype_expr): Restructure parsing of expressions != id-expressions. (cp_parser_postfix_expression, cp_parser_unary_expression): Adjust. /testsuite 2013-10-09 Paolo Carlini PR c++/58633 * g++.dg/cpp0x/decltype57.C: New. Index: cp/parser.c =================================================================== --- cp/parser.c (revision 203308) +++ cp/parser.c (working copy) @@ -1857,7 +1857,7 @@ static tree cp_parser_nested_name_specifier static tree cp_parser_qualifying_entity (cp_parser *, bool, bool, bool, bool, bool); static tree cp_parser_postfix_expression - (cp_parser *, bool, bool, bool, bool, cp_id_kind *); + (cp_parser *, bool, bool, bool, bool&, cp_id_kind *); static tree cp_parser_postfix_open_square_expression (cp_parser *, tree, bool, bool); static tree cp_parser_postfix_dot_deref_expression @@ -5531,14 +5531,14 @@ cp_parser_qualifying_entity (cp_parser *parser, `&' operator. CAST_P is true if this expression is the target of a cast. - If MEMBER_ACCESS_ONLY_P, we only allow postfix expressions that are - class member access expressions [expr.ref]. + If IS_MEMBER_ACCESS is false, we are not returning a class member + access expression [expr.ref]. Returns a representation of the expression. */ static tree cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, - bool member_access_only_p, bool decltype_p, + bool decltype_p, bool& is_member_access, cp_id_kind * pidk_return) { cp_token *token; @@ -5546,7 +5546,7 @@ cp_parser_postfix_expression (cp_parser *parser, b enum rid keyword; cp_id_kind idk = CP_ID_KIND_NONE; tree postfix_expression = NULL_TREE; - bool is_member_access = false; + is_member_access = false; /* Peek at the next token. */ token = cp_lexer_peek_token (parser->lexer); @@ -6066,10 +6066,7 @@ cp_parser_postfix_expression (cp_parser *parser, b default: if (pidk_return != NULL) * pidk_return = idk; - if (member_access_only_p) - return is_member_access? postfix_expression : error_mark_node; - else - return postfix_expression; + return postfix_expression; } } @@ -7003,9 +7000,9 @@ cp_parser_unary_expression (cp_parser *parser, boo return expression; } + bool is_member_access; return cp_parser_postfix_expression (parser, address_p, cast_p, - /*member_access_only_p=*/false, - decltype_p, + decltype_p, is_member_access, pidk); } @@ -11678,33 +11675,42 @@ cp_parser_decltype_expr (cp_parser *parser, id_expression_or_member_access_p = true; } - if (!id_expression_or_member_access_p) + if (id_expression_or_member_access_p) { - /* Abort the id-expression parse. */ - cp_parser_abort_tentative_parse (parser); + /* We have parsed an id-expression. */ + cp_parser_parse_definitely (parser); + return expr; + } - /* Parsing tentatively, again. */ - cp_parser_parse_tentatively (parser); + /* Abort the id-expression parse. */ + cp_parser_abort_tentative_parse (parser); - /* Parse a class member access. */ - expr = cp_parser_postfix_expression (parser, /*address_p=*/false, - /*cast_p=*/false, /*decltype*/true, - /*member_access_only_p=*/true, NULL); + /* Parsing tentatively, again. */ + cp_parser_parse_tentatively (parser); - if (expr - && expr != error_mark_node - && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN) - /* We have an id-expression. */ - id_expression_or_member_access_p = true; - } + /* Parse a postfix expression. */ + bool is_member_access; + expr = cp_parser_postfix_expression (parser, /*address_p=*/false, + /*cast_p=*/false, + /*decltype_p*/true, + is_member_access, NULL); - if (id_expression_or_member_access_p) - /* We have parsed the complete id-expression or member access. */ + bool postfix_expression_ok_p = + (expr && expr != error_mark_node + && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN); + + if (postfix_expression_ok_p + && is_member_access) + id_expression_or_member_access_p = true; + + if (postfix_expression_ok_p) + /* We have parsed a member access or a different kind of valid + postfix expression, eg, a pseudo destructor call [expr.pseudo] + (c++/58633). */ cp_parser_parse_definitely (parser); else { - /* Abort our attempt to parse an id-expression or member access - expression. */ + /* Abort our attempt to parse a postfix-expression. */ cp_parser_abort_tentative_parse (parser); /* Parse a full expression. */ Index: testsuite/g++.dg/cpp0x/decltype57.C =================================================================== --- testsuite/g++.dg/cpp0x/decltype57.C (revision 0) +++ testsuite/g++.dg/cpp0x/decltype57.C (working copy) @@ -0,0 +1,8 @@ +// PR c++/58633 +// { dg-do compile { target c++11 } } + +void foo(int i) +{ + typedef int I; + decltype(i.I::~I())* p; +}