From patchwork Thu Jun 16 22:03:23 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 100734 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 EBD2BB6F86 for ; Fri, 17 Jun 2011 08:03:41 +1000 (EST) Received: (qmail 10587 invoked by alias); 16 Jun 2011 22:03:39 -0000 Received: (qmail 10564 invoked by uid 22791); 16 Jun 2011 22:03:38 -0000 X-SWARE-Spam-Status: No, hits=-6.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, TW_TM, T_RP_MATCHES_RCVD 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; Thu, 16 Jun 2011 22:03:24 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5GM3OEU025035 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 16 Jun 2011 18:03:24 -0400 Received: from [127.0.0.1] (ovpn-113-143.phx2.redhat.com [10.3.113.143]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p5GM3O75011706 for ; Thu, 16 Jun 2011 18:03:24 -0400 Message-ID: <4DFA7DAB.3040208@redhat.com> Date: Thu, 16 Jun 2011 18:03:23 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc14 Lightning/1.0b2 Thunderbird/3.1.10 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for c++/44160 (__func__ and lambda) 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 Here since we hadn't called begin_compound_stmt yet for the simple return case, __func__ couldn't find a block scope to push into. So we open-code cp_parser_function_body and share the code between the two cases. Tested x86_64-pc-linux-gnu, applying to trunk. commit c748e82bb981d63bb24926fdd0f7bf89f6ee7aac Author: Jason Merrill Date: Wed Jun 15 15:21:56 2011 -0400 PR c++/44160 * parser.c (cp_parser_lambda_body): Share code between simple and complex cases instead of using cp_parser_function_body. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 961f9fe..5ea04b5 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -7731,6 +7731,7 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) tree fco = lambda_function (lambda_expr); tree body; bool done = false; + tree compound_stmt; /* Let the front end know that we are going to be defining this function. */ @@ -7741,6 +7742,11 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) start_lambda_scope (fco); body = begin_function_body (); + if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE)) + goto out; + + compound_stmt = begin_compound_stmt (0); + /* 5.1.1.4 of the standard says: If a lambda-expression does not include a trailing-return-type, it is as if the trailing-return-type denotes the following type: @@ -7757,11 +7763,9 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) in the body. Since we used void as the placeholder return type, parsing the body as usual will give such desired behavior. */ if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr) - && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE) - && cp_lexer_peek_nth_token (parser->lexer, 2)->keyword == RID_RETURN - && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_SEMICOLON) + && cp_lexer_peek_nth_token (parser->lexer, 1)->keyword == RID_RETURN + && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SEMICOLON) { - tree compound_stmt; tree expr = NULL_TREE; cp_id_kind idk = CP_ID_KIND_NONE; @@ -7769,7 +7773,6 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) statement. */ cp_parser_parse_tentatively (parser); - cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE); cp_parser_require_keyword (parser, RID_RETURN, RT_RETURN); expr = cp_parser_expression (parser, /*cast_p=*/false, &idk); @@ -7781,10 +7784,8 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) { apply_lambda_return_type (lambda_expr, lambda_return_type (expr)); - compound_stmt = begin_compound_stmt (0); /* Will get error here if type not deduced yet. */ finish_return_stmt (expr); - finish_compound_stmt (compound_stmt); done = true; } @@ -7794,12 +7795,16 @@ cp_parser_lambda_body (cp_parser* parser, tree lambda_expr) { if (!LAMBDA_EXPR_RETURN_TYPE (lambda_expr)) LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = true; - /* TODO: does begin_compound_stmt want BCS_FN_BODY? - cp_parser_compound_stmt does not pass it. */ - cp_parser_function_body (parser); + while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL)) + cp_parser_label_declaration (parser); + cp_parser_statement_seq_opt (parser, NULL_TREE); + cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE); LAMBDA_EXPR_DEDUCE_RETURN_TYPE_P (lambda_expr) = false; } + finish_compound_stmt (compound_stmt); + + out: finish_function_body (body); finish_lambda_scope (); diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__.C new file mode 100644 index 0000000..1cc7bb6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-__func__.C @@ -0,0 +1,9 @@ +// PR c++/44160 +// { dg-options -std=c++0x } +// { dg-do link } + +int main() +{ + const char *p = []() { return __func__; }(); + return p == 0; +}