On Mon, Aug 13, 2018 at 06:27:53PM +1200, Jason Merrill wrote: > On Sun, Aug 12, 2018 at 3:53 PM, Marek Polacek <pola...@redhat.com> wrote: > > - var = add_capture (lambda, > > - id, > > - initializer, > > - /*by_reference_p=*/ > > - (this_capture_p > > - || (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) > > - == CPLD_REFERENCE)), > > - /*explicit_init_p=*/false); > > + var = add_capture (lambda, id, initializer, > > + /*by_reference_p=*/ > > + (this_capture_p > > + || (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) > > + == CPLD_REFERENCE)), > > + /*explicit_init_p=*/false); > > This reformatting seems unnecessary, and I prefer to avoid unnecessary > reformatting to avoid noise in 'git blame'. The rest of the patch is > OK.
Thanks, this is what I committed. 2018-08-13 Marek Polacek <pola...@redhat.com> P0806R2 - Deprecate implicit capture of this via [=] * lambda.c (add_default_capture): Formatting fixes. Warn about deprecated implicit capture of this via [=]. * g++.dg/cpp2a/lambda-this1.C: New test. * g++.dg/cpp2a/lambda-this2.C: New test. * g++.dg/cpp2a/lambda-this3.C: New test. --- gcc/cp/lambda.c +++ gcc/cp/lambda.c @@ -695,14 +695,10 @@ tree add_default_capture (tree lambda_stack, tree id, tree initializer) { bool this_capture_p = (id == this_identifier); - tree var = NULL_TREE; - tree saved_class_type = current_class_type; - tree node; - - for (node = lambda_stack; + for (tree node = lambda_stack; node; node = TREE_CHAIN (node)) { @@ -720,6 +716,19 @@ add_default_capture (tree lambda_stack, tree id, tree initializer) == CPLD_REFERENCE)), /*explicit_init_p=*/false); initializer = convert_from_reference (var); + + /* Warn about deprecated implicit capture of this via [=]. */ + if (cxx_dialect >= cxx2a + && this_capture_p + && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda) == CPLD_COPY + && !in_system_header_at (LAMBDA_EXPR_LOCATION (lambda))) + { + if (warning_at (LAMBDA_EXPR_LOCATION (lambda), OPT_Wdeprecated, + "implicit capture of %qE via %<[=]%> is deprecated " + "in C++20", this_identifier)) + inform (LAMBDA_EXPR_LOCATION (lambda), "add explicit %<this%> or " + "%<*this%> capture"); + } } current_class_type = saved_class_type; --- gcc/testsuite/g++.dg/cpp2a/lambda-this1.C +++ gcc/testsuite/g++.dg/cpp2a/lambda-this1.C @@ -0,0 +1,51 @@ +// P0806R2 +// { dg-do compile } +// { dg-options "-std=c++2a" } + +struct X { + int x; + void foo (int n) { + auto a1 = [=] { x = n; }; // { dg-warning "implicit capture" } + auto a2 = [=, this] { x = n; }; + auto a3 = [=, *this]() mutable { x = n; }; + auto a4 = [&] { x = n; }; + auto a5 = [&, this] { x = n; }; + auto a6 = [&, *this]() mutable { x = n; }; + + auto a7 = [=] { // { dg-warning "implicit capture" } + auto a = [=] { // { dg-warning "implicit capture" } + auto a2 = [=] { x = n; }; // { dg-warning "implicit capture" } + }; + }; + + auto a8 = [=, this] { + auto a = [=, this] { + auto a2 = [=, this] { x = n; }; + }; + }; + + auto a9 = [=, *this]() mutable { + auto a = [=, *this]() mutable { + auto a2 = [=, *this]() mutable { x = n; }; + }; + }; + + auto a10 = [&] { + auto a = [&] { + auto a2 = [&] { x = n; }; + }; + }; + + auto a11 = [&, this] { + auto a = [&, this] { + auto a2 = [&, this] { x = n; }; + }; + }; + + auto a12 = [&, *this]() mutable { + auto a = [&, *this]() mutable { + auto a2 = [&, *this]() mutable { x = n; }; + }; + }; + } +}; --- gcc/testsuite/g++.dg/cpp2a/lambda-this2.C +++ gcc/testsuite/g++.dg/cpp2a/lambda-this2.C @@ -0,0 +1,51 @@ +// P0806R2 +// { dg-do compile } +// { dg-options "-std=c++2a -Wno-deprecated" } + +struct X { + int x; + void foo (int n) { + auto a1 = [=] { x = n; }; // { dg-bogus "implicit capture" } + auto a2 = [=, this] { x = n; }; + auto a3 = [=, *this]() mutable { x = n; }; + auto a4 = [&] { x = n; }; + auto a5 = [&, this] { x = n; }; + auto a6 = [&, *this]() mutable { x = n; }; + + auto a7 = [=] { // { dg-bogus "implicit capture" } + auto a = [=] { // { dg-bogus "implicit capture" } + auto a2 = [=] { x = n; }; // { dg-bogus "implicit capture" } + }; + }; + + auto a8 = [=, this] { + auto a = [=, this] { + auto a2 = [=, this] { x = n; }; + }; + }; + + auto a9 = [=, *this]() mutable { + auto a = [=, *this]() mutable { + auto a2 = [=, *this]() mutable { x = n; }; + }; + }; + + auto a10 = [&] { + auto a = [&] { + auto a2 = [&] { x = n; }; + }; + }; + + auto a11 = [&, this] { + auto a = [&, this] { + auto a2 = [&, this] { x = n; }; + }; + }; + + auto a12 = [&, *this]() mutable { + auto a = [&, *this]() mutable { + auto a2 = [&, *this]() mutable { x = n; }; + }; + }; + } +}; --- gcc/testsuite/g++.dg/cpp2a/lambda-this3.C +++ gcc/testsuite/g++.dg/cpp2a/lambda-this3.C @@ -0,0 +1,55 @@ +// P0806R2 +// { dg-do compile } +// { dg-options "-std=c++17" } + +struct X { + int x; + void foo (int n) { + auto a1 = [=] { x = n; }; // { dg-bogus "implicit capture" } + auto a2 = [=, this] { x = n; }; + // { dg-warning "explicit by-copy capture" "" { target c++17_down } .-1 } + auto a3 = [=, *this]() mutable { x = n; }; + auto a4 = [&] { x = n; }; + auto a5 = [&, this] { x = n; }; + auto a6 = [&, *this]() mutable { x = n; }; + + auto a7 = [=] { // { dg-bogus "implicit capture" } + auto a = [=] { // { dg-bogus "implicit capture" } + auto a2 = [=] { x = n; }; // { dg-bogus "implicit capture" } + }; + }; + + auto a8 = [=, this] { + // { dg-warning "explicit by-copy capture" "" { target c++17_down } .-1 } + auto a = [=, this] { + // { dg-warning "explicit by-copy capture" "" { target c++17_down } .-1 } + auto a2 = [=, this] { x = n; }; + // { dg-warning "explicit by-copy capture" "" { target c++17_down } .-1 } + }; + }; + + auto a9 = [=, *this]() mutable { + auto a = [=, *this]() mutable { + auto a2 = [=, *this]() mutable { x = n; }; + }; + }; + + auto a10 = [&] { + auto a = [&] { + auto a2 = [&] { x = n; }; + }; + }; + + auto a11 = [&, this] { + auto a = [&, this] { + auto a2 = [&, this] { x = n; }; + }; + }; + + auto a12 = [&, *this]() mutable { + auto a = [&, *this]() mutable { + auto a2 = [&, *this]() mutable { x = n; }; + }; + }; + } +};