]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: constexpr and lambda capture [PR90212]
authorJason Merrill <jason@redhat.com>
Mon, 25 May 2020 22:04:39 +0000 (18:04 -0400)
committerJason Merrill <jason@redhat.com>
Mon, 25 May 2020 22:04:42 +0000 (18:04 -0400)
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.

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp0x/lambda/lambda-constexpr2.C [new file with mode: 0644]

index 5704b62e8d40120c22c72b8230e61778dcbd51b0..421e8feac8d4a504176f223cc6e51bb018c32bce 100644 (file)
@@ -1,3 +1,9 @@
+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
index 637cb746576ec4423802d57808f95219dd0d993b..706d8a13d8ef4879d5ee58db315b7b8c9236e6e1 100644 (file)
@@ -7520,12 +7520,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 (file)
index 0000000..b1982ab
--- /dev/null
@@ -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; };
+}