]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: lambda capturing structured bindings [PR85889]
authorMarek Polacek <polacek@redhat.com>
Fri, 1 Mar 2024 22:13:02 +0000 (17:13 -0500)
committerMarek Polacek <polacek@redhat.com>
Thu, 9 May 2024 16:42:42 +0000 (12:42 -0400)
<https://wg21.link/p1381r1> clarifies that it's OK to capture structured
bindings.

[expr.prim.lambda.capture]/4 says "The identifier in a simple-capture shall
denote a local entity" and [basic.pre]/3: "An entity is a [...] structured
binding".

It doesn't appear that this was made a DR, so, strictly speaking, we
should have a -Wc++20-extensions warning, like clang++.

PR c++/85889

gcc/cp/ChangeLog:

* lambda.cc (add_capture): Add a pedwarn for capturing structured
bindings.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/decomp3.C: Use -Wno-c++20-extensions.
* g++.dg/cpp1z/decomp60.C: New test.

gcc/cp/lambda.cc
gcc/testsuite/g++.dg/cpp1z/decomp60.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp2a/decomp3.C

index 4b1f9391fee18fb55550175acfe8632f258af025..630cc4eade144211ff94c4408ba64706a12eabd3 100644 (file)
@@ -607,6 +607,16 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
                                         TCTX_CAPTURE_BY_COPY, type))
            return error_mark_node;
        }
+
+      if (cxx_dialect < cxx20)
+       {
+         auto_diagnostic_group d;
+         tree stripped_init = tree_strip_any_location_wrapper (initializer);
+         if (DECL_DECOMPOSITION_P (stripped_init)
+             && pedwarn (input_location, OPT_Wc__20_extensions,
+                         "captured structured bindings are a C++20 extension"))
+           inform (DECL_SOURCE_LOCATION (stripped_init), "declared here");
+       }
     }
 
   /* Add __ to the beginning of the field name so that user code
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp60.C b/gcc/testsuite/g++.dg/cpp1z/decomp60.C
new file mode 100644 (file)
index 0000000..b6117f3
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/85889
+// { dg-do compile { target c++17 } }
+// { dg-options "" }
+
+struct X { int i, j; };
+void f() {
+  X x{};
+  auto [i, j] = x;
+  [&i]() { }; // { dg-warning "captured structured bindings" "" { target c++17_only } }
+  [i]() { }; // { dg-warning "captured structured bindings" "" { target c++17_only } }
+}
+
index 5e77973d41f7918fc64d9f673423f9a5d2752678..25ab831997576506a4ae63ad27d2837546b4da27 100644 (file)
@@ -1,6 +1,6 @@
 // P1381R1
 // { dg-do compile { target c++11 } }
-// { dg-options "" }
+// { dg-options "-Wno-c++20-extensions" }
 
 struct Foo { int a : 1; int b; };