Tested x86_64-pc-linux-gnu, applying to trunk. -- 8< --
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. --- gcc/cp/lambda.cc | 2 +- .../g++.dg/cpp0x/lambda/lambda-constexpr3.C | 13 +++++++++++++ .../g++.dg/cpp0x/lambda/lambda-constexpr3a.C | 12 ++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr3a.C diff --git a/gcc/cp/lambda.cc b/gcc/cp/lambda.cc index ae732c3f72a..182cffaf8d4 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 00000000000..652521325f6 --- /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 00000000000..398e079f724 --- /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" } +} base-commit: e9549b5ee8496af12bac3ebfa3ec0aa8487fb725 -- 2.49.0