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.
{
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);
--- /dev/null
+// 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, ""); } ();
+}
--- /dev/null
+// 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" }
+}