From patchwork Mon Apr 22 19:19:22 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 238642 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 081932C0137 for ; Tue, 23 Apr 2013 05:19:34 +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:subject:content-type; q= dns; s=default; b=IVv9Jv5IVzM6xUJh/dxP8BW/E40ZeA+k/b6hAwVBsl4s8b 87krQKv9lf2VZt/WomgkblpK3s+RwI+LbX5O+n9bYuRdZEz5Yt4DCRz8xlrtpP/C rwP+WOPEOob18ynsXc2a48JFMAzlq4XulTgDqnlfDEd7CrMYjXZShiD5hvwlQ= 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:subject:content-type; s= default; bh=J73JotgNESiG/0ngCt8rKvgzZTg=; b=IKfy3w67tfcpDWLbpYC3 3ehY+XYlZwD7rFlHw8q5XGQ7mprPx5ZTTNnUB0dnCfKM+NPETVESlqI9BG4WK4Oe SJXYj5uDIXG9WXf6lddocVg7esTLHPvhPgJJQ70T36iryplhT1CkJkirkkX0B276 lFlfYGX6++kH75nWndff+sc= Received: (qmail 12453 invoked by alias); 22 Apr 2013 19:19:28 -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 12443 invoked by uid 89); 22 Apr 2013 19:19:28 -0000 X-Spam-SWARE-Status: No, score=-6.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS, SPF_PASS, TW_CX autolearn=ham version=3.3.1 Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Mon, 22 Apr 2013 19:19:27 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r3MJJQvh005060 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 22 Apr 2013 15:19:26 -0400 Received: from [10.36.116.23] (ovpn-116-23.ams2.redhat.com [10.36.116.23]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r3MJJNIr012829 for ; Mon, 22 Apr 2013 15:19:24 -0400 Message-ID: <51758D3A.1080305@redhat.com> Date: Mon, 22 Apr 2013 15:19:22 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; Linux i686; rv:22.0) Gecko/20100101 Thunderbird/22.0a2 MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH to add capture initializers to -std=c++1y X-Virus-Found: No At the Bristol C++ meeting we voted to accept generalized lambda capture initializers (e.g. [x = 42, y = std::move(y)]{ ... }), which were part of the initial implementation of lambdas in GCC, so initial support for C++1y is just a matter of checking cxx_dialect to avoid the pedwarn. The only thing missing from our implementation is support for list-initialization as well as = initialization; I'll add that soon. Tested x86_64-pc-linux-gnu, applying to trunk. commit a920644105779dceffd5912822b10b331457a227 Author: Jason Merrill Date: Mon Apr 22 12:56:01 2013 -0400 N3648 * parser.c (cp_parser_lambda_introducer): Make lambda capture init pedwarn unconditional except in C++1y mode. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 1893482..1fbc9bd 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -8518,9 +8518,10 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) { /* An explicit expression exists. */ cp_lexer_consume_token (parser->lexer); - pedwarn (input_location, OPT_Wpedantic, - "ISO C++ does not allow initializers " - "in lambda expression capture lists"); + if (cxx_dialect < cxx1y) + pedwarn (input_location, 0, + "lambda capture initializers " + "only available with -std=c++1y or -std=gnu++1y"); capture_init_expr = cp_parser_assignment_expression (parser, /*cast_p=*/true, &idk); diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C deleted file mode 100644 index 9b5ab79..0000000 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-deduce-ext.C +++ /dev/null @@ -1,27 +0,0 @@ -// Testcase for an extension to allow return type deduction when the lambda -// contains more than just a single return-statement. - -// { dg-options -std=c++0x } -// { dg-do run } - -bool b; -template -T f (T t) -{ - return [=] { - auto i = t+1; - if (b) - return i+1; - else - return i+1; - }(); -} - -int main() -{ - // Pointless, but well-formed. - [] { return 1; return 2; }(); - - if (f(1) != 3) - return 1; -} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C deleted file mode 100644 index 03c94e9..0000000 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-init.C +++ /dev/null @@ -1,8 +0,0 @@ -// Test for the explicit initializer extension -// { dg-options "-std=c++0x" } - -int main() -{ - int j = [i = 2]{sizeof(i); return i;}(); - return (j != 2); -} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-deduce-mult.C b/gcc/testsuite/g++.dg/cpp1y/lambda-deduce-mult.C new file mode 100644 index 0000000..1181a80 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-deduce-mult.C @@ -0,0 +1,27 @@ +// Testcase for an extension to allow return type deduction when the lambda +// contains more than just a single return-statement. + +// { dg-options -std=c++1y } +// { dg-do run } + +bool b; +template +T f (T t) +{ + return [=] { + auto i = t+1; + if (b) + return i+1; + else + return i+1; + }(); +} + +int main() +{ + // Pointless, but well-formed. + [] { return 1; return 2; }(); + + if (f(1) != 3) + return 1; +} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init.C new file mode 100644 index 0000000..a443642 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init.C @@ -0,0 +1,8 @@ +// Test for the explicit initializer extension of C++1y +// { dg-options "-std=c++1y" } + +int main() +{ + int j = [i = 2]{sizeof(i); return i;}(); + return (j != 2); +} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init1.C new file mode 100644 index 0000000..6411fca --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init1.C @@ -0,0 +1,13 @@ +// N3648: capture init +// { dg-options "-std=c++1y -w" } +// { dg-do run } + +int main() +{ + int x = 41; + auto r = [x = x+1]{ return x; }(); + if (r != 42) __builtin_abort(); + + static auto *p = &r; + [&x=r]{ if (&x != p) __builtin_abort(); }(); +} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init2.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init2.C new file mode 100644 index 0000000..068621d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init2.C @@ -0,0 +1,13 @@ +// N3648: redundancy and capture init +// { dg-options "-std=c++1y -pedantic-errors" } + +int main() +{ + int x = 42; + [=,x]{}; // { dg-error "redundant" } + [=,&x]{}; + [&,&x]{}; // { dg-error "redundant" } + [&,x]{}; + [=,x=24]{}; + [&,&r=x]{}; +} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init3.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init3.C new file mode 100644 index 0000000..9044be6 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init3.C @@ -0,0 +1,11 @@ +// N3648: capture init at non-block scope +// { dg-options "-std=c++1y -w" } +// { dg-do run } + +int i = 42; +int j = [x=i]{ return x; }(); + +int main() +{ + if (j != 42) __builtin_abort(); +} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init4.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init4.C new file mode 100644 index 0000000..da4ea37 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init4.C @@ -0,0 +1,14 @@ +// N3648: capture init example from paper +// { dg-options "-std=c++1y" } +// { dg-do run } + +int x = 4; +auto y = [&r = x, x = x+1]()->int { + r += 2; + return x+2; +}(); // Updates ::x to 6, and initializes y to 7. + +int main() +{ + if (x != 6 || y != 7) __builtin_abort(); +}