https://gcc.gnu.org/g:387cc9f80fcfd8b7d3fc142ef01bb05a46f0f244
commit r16-1992-g387cc9f80fcfd8b7d3fc142ef01bb05a46f0f244 Author: Jason Merrill <ja...@redhat.com> Date: Thu Jul 3 16:52:56 2025 -0400 c++: trivial lambda pruning [PR120716] In this testcase there is nothing in the lambda except a static_assert which mentions a variable from the enclosing scope but does not odr-use it, so we want prune_lambda_captures to remove its capture. Since the lambda is so empty, there's nothing in the body except the DECL_EXPR of the capture proxy, so pop_stmt_list moves that into the enclosing STATEMENT_LIST and passes the 'body' STATEMENT_LIST to free_stmt_list. As a result, passing 'body' to prune_lambda_captures is wrong; we should instead pass the enclosing scope, i.e. cur_stmt_list. PR c++/120716 gcc/cp/ChangeLog: * lambda.cc (finish_lambda_function): Pass cur_stmt_list to prune_lambda_captures. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/lambda/lambda-constexpr3.C: New test. * g++.dg/cpp0x/lambda/lambda-constexpr3a.C: New test. Diff: --- gcc/cp/lambda.cc | 2 +- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3.C | 13 +++++++++++++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3a.C | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index ae732c3f72a6..182cffaf8d4f 100644 --- a/gcc/cp/lambda.cc +++ b/gcc/cp/lambda.cc @@ -1950,7 +1950,7 @@ finish_lambda_function (tree body) { finish_function_body (body); - prune_lambda_captures (body); + prune_lambda_captures (cur_stmt_list); /* Finish the function and generate code for it if necessary. */ tree fn = finish_function (/*inline_p=*/true); diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3.C new file mode 100644 index 000000000000..652521325f68 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3.C @@ -0,0 +1,13 @@ +// PR c++/120716 +// { dg-do compile { target c++11 } } + +struct A { int *r; }; + +void +foo () +{ + static int i; + constexpr A a = { &i }; + static_assert (a.r == &i, ""); + [&] { static_assert (a.r != nullptr, ""); } (); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3a.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3a.C new file mode 100644 index 000000000000..398e079f7246 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3a.C @@ -0,0 +1,12 @@ +// PR c++/120716 +// { dg-do compile { target c++11 } } + +struct A { int *const &r; }; + +void +foo (int x) +{ + constexpr A a = { &x }; // { dg-error "constant" } + static_assert (a.r == &x, ""); // { dg-error "non-constant" } + [&] { static_assert (a.r != nullptr, ""); } (); // { dg-error "non-constant" } +}