aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-05-25 18:38:09 -0400
committerJason Merrill <jason@redhat.com>2020-05-25 18:38:11 -0400
commit0296697cf9893dc9509cdcd8e3fd4ba9fe422527 (patch)
tree4afde3d10d63d3fb30cc3d87c129bc995c99a447
parente153e0ef3a35c2c72e8bf89bd905fe27f8877852 (diff)
c++: constexpr and lambda capture [PR90212]
This is the same issue as PR86429, just in potential_constant_expression_1 rather than cxx_eval_constant_expression. As in that case, when we're trying to evaluate a constant expression within a lambda, we don't have a constant closure object to refer to, but we can try to refer directly to the captured variable. gcc/cp/ChangeLog 2020-05-05 Jason Merrill <jason@redhat.com> PR c++/90212 * constexpr.c (potential_constant_expression_1): In a lambda function, consider a captured variable directly.
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/constexpr.c8
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr2.C13
3 files changed, 26 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7626511b9ca..87fb9c0147a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2020-05-25 Jason Merrill <jason@redhat.com>
+ PR c++/90212
+ * constexpr.c (potential_constant_expression_1): In a lambda
+ function, consider a captured variable directly.
+
+2020-05-25 Jason Merrill <jason@redhat.com>
+
PR c++/90479
* init.c (get_nsdmi): Don't push_to_top_level for a local class.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index b349919b434..3465f1db54b 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -6159,12 +6159,18 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
variable with automatic storage duration defined outside that
lambda-expression, where the reference would be an
odr-use. */
+
+ if (want_rval)
+ /* Since we're doing an lvalue-rvalue conversion, this might
+ not be an odr-use, so evaluate the variable directly. */
+ return RECUR (DECL_CAPTURED_VARIABLE (t), rval);
+
if (flags & tf_error)
{
tree cap = DECL_CAPTURED_VARIABLE (t);
error ("lambda capture of %qE is not a constant expression",
cap);
- if (!want_rval && decl_constant_var_p (cap))
+ if (decl_constant_var_p (cap))
inform (input_location, "because it is used as a glvalue");
}
return false;
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr2.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr2.C
new file mode 100644
index 00000000000..b1982ab0506
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr2.C
@@ -0,0 +1,13 @@
+// PR c++/90212
+// { dg-do compile { target c++11 } }
+
+template<typename T> struct tuple {
+ constexpr tuple(T&& t) : t(t) { }
+ int t;
+};
+
+void foo() {
+ constexpr tuple<int> v1{1};
+ constexpr auto v2 = v1;
+ [&]{ constexpr auto v2 = v1; };
+}