From patchwork Fri May 17 00:22:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 244454 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 CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 87DB92C009E for ; Fri, 17 May 2013 10:22:41 +1000 (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=wZVmaOE22GBooFAetC8JpkFNznmwWZqa3ulYDniQGM/ WeTwu3X98hYFpWKgA/BmR7uvVF89YbmfnV8i+bo5Ogq6Q4bzgoJjjb3uhurJw64b 8GThRSmXne4fd7aZbEIo9+EsB7BMAJWykNw7NVBuMccf1/AU+C6cxlAAvxPH56QE = 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=ggX+9edz3Wubo8m79e8zfw3EXNY=; b=BHZ7GccQ4y4hoxNAb HYOuWYSNA0vj3p9Z7pyKCpXk9sDJyICQ1Ubu0tPrQsiqPckERDHB2VAjd9qbkRxO gm84F928yDvA2NXfE3sKsZscYRganASgzmaRqg0LcE+FFwrIHfqUrmv9GoYftgSF IlK3GkvY/EKjpA9ytPtnhnso1U= Received: (qmail 28184 invoked by alias); 17 May 2013 00:22:35 -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 28157 invoked by uid 89); 17 May 2013 00:22:30 -0000 X-Spam-SWARE-Status: No, score=-5.7 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_MED, RCVD_IN_HOSTKARMA_NO, RCVD_IN_HOSTKARMA_YE, RP_MATCHES_RCVD, SPF_PASS, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Fri, 17 May 2013 00:22:29 +0000 Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by userp1040.oracle.com (Sentrion-MTA-4.3.1/Sentrion-MTA-4.3.1) with ESMTP id r4H0MPoZ031690 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 17 May 2013 00:22:26 GMT Received: from userz7022.oracle.com (userz7022.oracle.com [156.151.31.86]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r4H0MPPG019360 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 17 May 2013 00:22:26 GMT Received: from abhmt119.oracle.com (abhmt119.oracle.com [141.146.116.71]) by userz7022.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id r4H0MPF9020469; Fri, 17 May 2013 00:22:25 GMT Received: from poldo4.casa (/79.25.197.81) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 16 May 2013 17:22:24 -0700 Message-ID: <5195783E.1040006@oracle.com> Date: Fri, 17 May 2013 02:22:22 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130329 Thunderbird/17.0.5 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: [C++ Patch] PR 18126 X-Virus-Found: No Hi, in this old issue Joseph pointed out that the C++ parser doesn't accept the GNU Extension 'sizeof compound-literal' and provided indications about the way to approach it. Indeed, I found very easy to use in cp_parser_sizeof_operand the same approach adopted in cp_parser_cast_expression (modulo the comments, only a few lines of code). Tested x86_64-linux. Thanks, Paolo. ///////////////////////// /cp 2013-05-17 Paolo Carlini PR c++/18126 * parser.c (cp_parser_sizeof_operand): As a GNU Extension, parse correctly sizeof compound-literal; update comments. /testsuite 2013-05-17 Paolo Carlini PR c++/18126 * g++.dg/ext/sizeof-complit.C: New. Index: cp/parser.c =================================================================== --- cp/parser.c (revision 198994) +++ cp/parser.c (working copy) @@ -6591,6 +6591,9 @@ cp_parser_pseudo_destructor_name (cp_parser* parse __real__ cast-expression __imag__ cast-expression && identifier + sizeof ( type-id ) { initializer-list , [opt] } + alignof ( type-id ) { initializer-list , [opt] } [C++0x] + __alignof__ ( type-id ) { initializer-list , [opt] } ADDRESS_P is true iff the unary-expression is appearing as the operand of the `&' operator. CAST_P is true if this expression is @@ -13968,6 +13971,7 @@ cp_parser_type_specifier (cp_parser* parser, __int128 __typeof__ unary-expression __typeof__ ( type-id ) + __typeof__ ( type-id ) { initializer-list , [opt] } Returns the indicated TYPE_DECL. If DECL_SPECS is not NULL, it is appropriately updated. */ @@ -22988,21 +22992,44 @@ cp_parser_sizeof_operand (cp_parser* parser, enum construction. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) { - tree type; - bool saved_in_type_id_in_expr_p; + tree type = NULL_TREE; + bool compound_literal_p; /* We can't be sure yet whether we're looking at a type-id or an expression. */ cp_parser_parse_tentatively (parser); /* Consume the `('. */ cp_lexer_consume_token (parser->lexer); - /* Parse the type-id. */ - saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p; - parser->in_type_id_in_expr_p = true; - type = cp_parser_type_id (parser); - parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p; - /* Now, look for the trailing `)'. */ - cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + /* Note: as a GNU Extension, compound literals are considered + postfix-expressions as they are in C99, so they are valid + arguments to sizeof. See comment in cp_parser_cast_expression + for details. */ + cp_lexer_save_tokens (parser->lexer); + /* Skip tokens until the next token is a closing parenthesis. + If we find the closing `)', and the next token is a `{', then + we are looking at a compound-literal. */ + compound_literal_p + = (cp_parser_skip_to_closing_parenthesis (parser, false, false, + /*consume_paren=*/true) + && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)); + /* Roll back the tokens we skipped. */ + cp_lexer_rollback_tokens (parser->lexer); + /* If we were looking at a compound-literal, simulate an error + so that the call to cp_parser_parse_definitely below will + fail. */ + if (compound_literal_p) + cp_parser_simulate_error (parser); + else + { + bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p; + parser->in_type_id_in_expr_p = true; + /* Look for the type-id. */ + type = cp_parser_type_id (parser); + /* Look for the closing `)'. */ + cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); + parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p; + } + /* If all went well, then we're done. */ if (cp_parser_parse_definitely (parser)) { Index: testsuite/g++.dg/ext/sizeof-complit.C =================================================================== --- testsuite/g++.dg/ext/sizeof-complit.C (revision 0) +++ testsuite/g++.dg/ext/sizeof-complit.C (working copy) @@ -0,0 +1,5 @@ +// PR c++/18126 +// { dg-options "" } + +struct s { int a; int b; }; +char x[((sizeof (struct s){ 1, 2 }) == sizeof (struct s)) ? 1 : -1];