https://gcc.gnu.org/g:dff57d76ad3c78cedaf2f8caa1686acb5059303d

commit r16-3069-gdff57d76ad3c78cedaf2f8caa1686acb5059303d
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Aug 7 16:38:51 2025 +0200

    c++: Implement C++26 P1061R10 - Structured Bindings can introduce a Pack 
[PR117783]
    
    The following patch implements the C++26
    P1061R10 - Structured Bindings can introduce a Pack
    paper.
    One thing unresolved in the patch is mangling, I've raised
    https://github.com/itanium-cxx-abi/cxx-abi/issues/200
    for that but no comments there yet.  One question is if it is ok
    not to mention the fact that there is a structured binding pack in
    the mangling of the structured bindings but more important is in case
    of std::tuple* we might need to mangle individual structured binding
    pack elements separately (each might need an exported name for the
    var itself and perhaps its guard variable as well).  The patch just
    uses the normal mangling for the whole structured bindings and emits
    sorry if we need to mangle the structured binding pack elements.
    The patch just marks the structured binding pack specially (considered
    e.g. using some bit on it, but in the end I'm identifying it using
    a made up type which causes DECL_PACK_P to be true; it is kind of
    self-referential solution, because the type on the pack mentions the
    DECL_DECOMPOSITION_P VAR_DECL on which the type is attached as its pack,
    so it needs to be handled carefully during instantiation to avoid infinite
    recursion, but it is the type that should be used if something else actually
    needs to use the same type as the structured binding pack, e.g. a capture
    proxy), and stores the pack elements when actually processed through
    cp_finish_decomp with non-dependent initializer into a TREE_VEC used as
    DECL_VALUE_EXPR of the pack; though because several spots use the
    DECL_VALUE_EXPR and assume it is ARRAY_REF from which they can find out the
    base variable and the index, it stores the base variable and index in the
    first 2 TREE_VEC elts and has the structured binding elements only after
    that.
    https://eel.is/c++draft/temp.dep.expr#3.6 says the packs are type dependent
    regardless of whether the initializer of the structured binding is type
    dependent or not, so I hope having a dependent type on the structured
    binding VAR_DECL is ok.
    The paper also has an exception for sizeof... which is then not value
    dependent when the structured bindings are initialized with non-dependent
    initializer: https://eel.is/c++draft/temp.dep.constexpr#4
    The patch special cases that in 3 spots (I've been wondering if e.g. during
    parsing I couldn't just fold the sizeof... to the INTEGER_CST right away,
    but guess I'd need to repeat that also during partial instantiation).
    
    And one thing still unresolved is debug info, I've just added DECL_IGNORED_P
    on the structured binding pack VAR_DECL because there were ICEs with -g
    for now, hope it can be fixed incrementally but am not sure what exactly
    we should emit in the debug info for that.
    
    Speaking of which, I see
    DW_TAG_GNU_template_parameter_pack
    DW_TAG_GNU_formal_parameter_pack
    etc. DIEs emitted regardless of DWARF version, shouldn't we try to upstream
    those into DWARF 6 or check what other compilers emit for the packs?
    And bet we'd need DW_TAG_GNU_structured_binding_pack as well.
    
    2025-08-07  Jakub Jelinek  <ja...@redhat.com>
    
            PR c++/117783
    gcc/c-family/
            * c-cppbuiltin.cc (c_cpp_builtins): Change __cpp_structured_bindings
            predefined value for C++26 from 202403L to 202411L.
    gcc/cp/
            * parser.cc: Implement C++26 P1061R10 - Structured Bindings can
            introduce a Pack.
            (cp_parser_range_for): Also handle TREE_VEC as DECL_VALUE_EXPR
            instead of ARRAY_REF.
            (cp_parser_decomposition_declaration): Use sb-identifier-list 
instead
            of identifier-list in comments.  Parse structured bindings with
            structured binding pack.  Don't emit pedwarn about structured
            binding attributes in structured bindings inside of a condition.
            (cp_convert_omp_range_for): Also handle TREE_VEC as DECL_VALUE_EXPR
            instead of ARRAY_REF.
            * decl.cc (get_tuple_element_type): Change i argument type from
            unsigned to unsigned HOST_WIDE_INT.
            (get_tuple_decomp_init): Likewise.
            (set_sb_pack_name): New function.
            (cp_finish_decomp): Handle structured binding packs.
            * pt.cc (tsubst_pack_expansion): Handle structured binding packs
            and capture proxies for them.  Formatting fixes.
            (tsubst_decl): For structured binding packs don't tsubst TREE_TYPE
            first, instead recreate the type after r is created.
            (tsubst_omp_for_iterator): Also handle TREE_VEC as DECL_VALUE_EXPR
            instead of ARRAY_REF.
            (tsubst_expr): Handle sizeof... on non-dependent structure binding
            packs.
            (value_dependent_expression_p): Return false for sizeof... on
            non-dependent structure binding packs.
            (instantiation_dependent_r): Don't recurse on sizeof... on
            non-dependent structure binding packs.
            * constexpr.cc (potential_constant_expression_1): Also handle
            TREE_VEC on DECL_VALUE_EXPR of structure binding packs.
    gcc/testsuite/
            * g++.dg/cpp26/decomp13.C: New test.
            * g++.dg/cpp26/decomp14.C: New test.
            * g++.dg/cpp26/decomp15.C: New test.
            * g++.dg/cpp26/decomp16.C: New test.
            * g++.dg/cpp26/decomp17.C: New test.
            * g++.dg/cpp26/decomp18.C: New test.
            * g++.dg/cpp26/decomp19.C: New test.
            * g++.dg/cpp26/decomp20.C: New test.
            * g++.dg/cpp26/decomp21.C: New test.
            * g++.dg/cpp26/feat-cxx26.C (__cpp_structured_bindings): Expect
            202411 rather than 202403.

Diff:
---
 gcc/c-family/c-cppbuiltin.cc            |   2 +-
 gcc/cp/constexpr.cc                     |   8 +-
 gcc/cp/decl.cc                          | 241 ++++++++++++++--
 gcc/cp/parser.cc                        |  81 +++++-
 gcc/cp/pt.cc                            | 117 +++++++-
 gcc/testsuite/g++.dg/cpp26/decomp13.C   |  52 ++++
 gcc/testsuite/g++.dg/cpp26/decomp14.C   | 474 ++++++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp26/decomp15.C   | 474 ++++++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp26/decomp16.C   | 240 ++++++++++++++++
 gcc/testsuite/g++.dg/cpp26/decomp17.C   |  28 ++
 gcc/testsuite/g++.dg/cpp26/decomp18.C   | 109 ++++++++
 gcc/testsuite/g++.dg/cpp26/decomp19.C   |  46 ++++
 gcc/testsuite/g++.dg/cpp26/decomp20.C   |  53 ++++
 gcc/testsuite/g++.dg/cpp26/decomp21.C   | 103 +++++++
 gcc/testsuite/g++.dg/cpp26/feat-cxx26.C |   4 +-
 15 files changed, 1990 insertions(+), 42 deletions(-)

diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index 4aea90288631..5476d102cc4c 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -1090,7 +1090,7 @@ c_cpp_builtins (cpp_reader *pfile)
          cpp_define (pfile, "__cpp_constexpr_exceptions=202411L");
          cpp_define (pfile, "__cpp_static_assert=202306L");
          cpp_define (pfile, "__cpp_placeholder_variables=202306L");
-         cpp_define (pfile, "__cpp_structured_bindings=202403L");
+         cpp_define (pfile, "__cpp_structured_bindings=202411L");
          cpp_define (pfile, "__cpp_deleted_function=202403L");
          cpp_define (pfile, "__cpp_variadic_friend=202403L");
          cpp_define (pfile, "__cpp_pack_indexing=202311L");
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index b8ac454ff728..eabf7f8a24d7 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -11615,12 +11615,14 @@ potential_constant_expression_1 (tree t, bool 
want_rval, bool strict, bool now,
                }
              return false;
            }
+         tree ve = DECL_VALUE_EXPR (t);
          /* Treat __PRETTY_FUNCTION__ inside a template function as
             potentially-constant.  */
-         else if (DECL_PRETTY_FUNCTION_P (t)
-                  && DECL_VALUE_EXPR (t) == error_mark_node)
+         if (DECL_PRETTY_FUNCTION_P (t) && ve == error_mark_node)
            return true;
-         return RECUR (DECL_VALUE_EXPR (t), rval);
+         if (DECL_DECOMPOSITION_P (t) && TREE_CODE (ve) == TREE_VEC)
+           return RECUR (TREE_VEC_ELT (ve, 0), rval);
+         return RECUR (ve, rval);
        }
       if (want_rval
          && (now || !var_in_maybe_constexpr_fn (t))
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 8122fca0af1b..ab5b0c974886 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -9748,7 +9748,7 @@ get_tuple_size (tree type)
 /* Return std::tuple_element<I,TYPE>::type.  */
 
 static tree
-get_tuple_element_type (tree type, unsigned i)
+get_tuple_element_type (tree type, unsigned HOST_WIDE_INT i)
 {
   tree args = make_tree_vec (2);
   TREE_VEC_ELT (args, 0) = build_int_cst (integer_type_node, i);
@@ -9764,7 +9764,7 @@ get_tuple_element_type (tree type, unsigned i)
 /* Return e.get<i>() or get<i>(e).  */
 
 static tree
-get_tuple_decomp_init (tree decl, unsigned i)
+get_tuple_decomp_init (tree decl, unsigned HOST_WIDE_INT i)
 {
   tree targs = make_tree_vec (1);
   TREE_VEC_ELT (targs, 0) = build_int_cst (integer_type_node, i);
@@ -9870,6 +9870,19 @@ cp_maybe_mangle_decomp (tree decl, cp_decomp *decomp)
     }
 }
 
+/* Append #i to DECL_NAME (decl).  */
+
+static void
+set_sb_pack_name (tree decl, unsigned HOST_WIDE_INT i)
+{
+  tree name = DECL_NAME (decl);
+  size_t len = IDENTIFIER_LENGTH (name) + 22;
+  char *n = XALLOCAVEC (char, len);
+  snprintf (n, len, "%s#" HOST_WIDE_INT_PRINT_UNSIGNED,
+           IDENTIFIER_POINTER (name), i);
+  DECL_NAME (decl) = get_identifier (n);
+}
+
 /* Finish a decomposition declaration.  DECL is the underlying declaration
    "e", FIRST is the head of a chain of decls for the individual identifiers
    chained through DECL_CHAIN in reverse order and COUNT is the number of
@@ -9926,10 +9939,13 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
   auto_vec<tree, 16> v;
   v.safe_grow (count, true);
   tree d = first;
+  int pack = -1;
   for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
     {
       v[count - i - 1] = d;
       fit_decomposition_lang_decl (d, decl);
+      if (DECL_PACK_P (d))
+       pack = count - i - 1;
     }
 
   tree type = TREE_TYPE (decl);
@@ -9951,6 +9967,14 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
 
   tree eltype = NULL_TREE;
   unsigned HOST_WIDE_INT eltscnt = 0;
+  /* Structured binding packs when initializer is non-dependent should
+     have their DECL_VALUE_EXPR set to a TREE_VEC.  First two elements
+     of that TREE_VEC are the base and index, what is normally represented
+     as DECL_VALUE_EXPR ARRAY_REF <base, index> where index is the index
+     of the pack first element.  The remaining elements of the TREE_VEC
+     are VAR_DECLs for the pack elements.  */
+  tree packv = NULL_TREE;
+
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
       tree nelts;
@@ -9969,7 +9993,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
          goto error_out;
        }
       eltscnt = tree_to_uhwi (nelts);
-      if (count != eltscnt)
+      if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
        {
        cnt_mismatch:
          auto_diagnostic_group d;
@@ -9990,12 +10014,37 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
       eltype = TREE_TYPE (type);
       for (unsigned int i = 0; i < count; i++)
        {
+         if ((unsigned) pack == i)
+           {
+             packv = make_tree_vec (eltscnt - count + 3);
+             for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+               {
+                 tree t;
+                 TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+                 set_sb_pack_name (t, j);
+                 maybe_push_decl (t);
+                 TREE_TYPE (t) = eltype;
+                 layout_decl (t, 0);
+                 if (!processing_template_decl)
+                   {
+                     tree a = unshare_expr (dexp);
+                     a = build4 (ARRAY_REF, eltype, a, size_int (j + pack),
+                                 NULL_TREE, NULL_TREE);
+                     SET_DECL_VALUE_EXPR (t, a);
+                     DECL_HAS_VALUE_EXPR_P (t) = 1;
+                   }
+               }
+             continue;
+           }
          TREE_TYPE (v[i]) = eltype;
          layout_decl (v[i], 0);
          if (processing_template_decl)
            continue;
          tree t = unshare_expr (dexp);
-         t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE);
+         unsigned HOST_WIDE_INT j = i;
+         if (pack != -1 && (unsigned) pack < i)
+           j = i + eltscnt - count;
+         t = build4 (ARRAY_REF, eltype, t, size_int (j), NULL_TREE, NULL_TREE);
          SET_DECL_VALUE_EXPR (v[i], t);
          DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
        }
@@ -10004,17 +10053,41 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
   else if (TREE_CODE (type) == COMPLEX_TYPE)
     {
       eltscnt = 2;
-      if (count != eltscnt)
+      if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
        goto cnt_mismatch;
       eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
       for (unsigned int i = 0; i < count; i++)
        {
+         if ((unsigned) pack == i)
+           {
+             packv = make_tree_vec (eltscnt - count + 3);
+             for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+               {
+                 tree t;
+                 TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+                 set_sb_pack_name (t, j);
+                 maybe_push_decl (t);
+                 TREE_TYPE (t) = eltype;
+                 layout_decl (t, 0);
+                 if (!processing_template_decl)
+                   {
+                     tree a = build1 (pack + j ? IMAGPART_EXPR : 
REALPART_EXPR, eltype,
+                                      unshare_expr (dexp));
+                     SET_DECL_VALUE_EXPR (t, a);
+                     DECL_HAS_VALUE_EXPR_P (t) = 1;
+                   }
+               }
+             continue;
+           }
          TREE_TYPE (v[i]) = eltype;
          layout_decl (v[i], 0);
          if (processing_template_decl)
            continue;
          tree t = unshare_expr (dexp);
-         t = build1 (i ? IMAGPART_EXPR : REALPART_EXPR, eltype, t);
+         unsigned HOST_WIDE_INT j = i;
+         if (pack != -1 && (unsigned) pack < i)
+           j = i + eltscnt - count;
+         t = build1 (j ? IMAGPART_EXPR : REALPART_EXPR, eltype, t);
          SET_DECL_VALUE_EXPR (v[i], t);
          DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
        }
@@ -10026,19 +10099,47 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
          error_at (loc, "cannot decompose variable length vector %qT", type);
          goto error_out;
        }
-      if (count != eltscnt)
+      if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
        goto cnt_mismatch;
       eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
       for (unsigned int i = 0; i < count; i++)
        {
+         if ((unsigned) pack == i)
+           {
+             packv = make_tree_vec (eltscnt - count + 3);
+             for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+               {
+                 tree t;
+                 TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+                 set_sb_pack_name (t, j);
+                 maybe_push_decl (t);
+                 TREE_TYPE (t) = eltype;
+                 layout_decl (t, 0);
+                 if (!processing_template_decl)
+                   {
+                     tree a = unshare_expr (dexp);
+                     location_t loc = DECL_SOURCE_LOCATION (t);
+                     tree s = size_int (j + pack);
+                     convert_vector_to_array_for_subscript (loc, &a, s);
+                     a = build4 (ARRAY_REF, eltype, a, s,
+                                 NULL_TREE, NULL_TREE);
+                     SET_DECL_VALUE_EXPR (t, a);
+                     DECL_HAS_VALUE_EXPR_P (t) = 1;
+                   }
+               }
+             continue;
+           }
          TREE_TYPE (v[i]) = eltype;
          layout_decl (v[i], 0);
          if (processing_template_decl)
            continue;
          tree t = unshare_expr (dexp);
+         unsigned HOST_WIDE_INT j = i;
+         if (pack != -1 && (unsigned) pack < i)
+           j = i + eltscnt - count;
          convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]),
-                                                &t, size_int (i));
-         t = build4 (ARRAY_REF, eltype, t, size_int (i), NULL_TREE, NULL_TREE);
+                                                &t, size_int (j));
+         t = build4 (ARRAY_REF, eltype, t, size_int (j), NULL_TREE, NULL_TREE);
          SET_DECL_VALUE_EXPR (v[i], t);
          DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
        }
@@ -10062,11 +10163,11 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
          goto error_out;
        }
       eltscnt = tree_to_uhwi (tsize);
-      if (count != eltscnt)
+      if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
        goto cnt_mismatch;
-      if (test_p)
+      if (test_p && eltscnt)
        return true;
-      if (!processing_template_decl && DECL_DECOMP_BASE (decl))
+      if (!processing_template_decl && DECL_DECOMP_BASE (decl) && eltscnt)
        {
          /* For structured bindings used in conditions we need to evaluate
             the conversion of decl (aka e in the standard) to bool or
@@ -10096,16 +10197,70 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
          location_t sloc = input_location;
          location_t dloc = DECL_SOURCE_LOCATION (v[i]);
 
+         if ((unsigned) pack == i)
+           {
+             packv = make_tree_vec (eltscnt - count + 3);
+             for (unsigned HOST_WIDE_INT j = 0; j < eltscnt - count + 1; ++j)
+               {
+                 tree t;
+                 TREE_VEC_ELT (packv, j + 2) = t = copy_node (v[pack]);
+                 set_sb_pack_name (t, j);
+                 input_location = dloc;
+                 tree init = get_tuple_decomp_init (decl, j + pack);
+                 tree eltype = (init == error_mark_node ? error_mark_node
+                                : get_tuple_element_type (type, j + pack));
+                 input_location = sloc;
+
+                 if (VOID_TYPE_P (eltype))
+                   {
+                     error ("%<std::tuple_element<%wu, %T>::type%> is "
+                            "%<void%>", j + pack, type);
+                     eltype = error_mark_node;
+                   }
+                 if (init == error_mark_node || eltype == error_mark_node)
+                   {
+                     inform (dloc, "in initialization of structured binding "
+                             "pack %qD", v[pack]);
+                     goto error_out;
+                   }
+                 if (j == 0
+                     && !processing_template_decl
+                     && TREE_STATIC (decl))
+                   {
+                     sorry_at (dloc, "mangling of structured binding pack "
+                                     "elements not implemented yet");
+                     goto error_out;
+                   }
+                 maybe_push_decl (t);
+                 /* Save the decltype away before reference collapse.  */
+                 hash_map_safe_put<hm_ggc> (decomp_type_table, t, eltype);
+                 eltype = cp_build_reference_type (eltype, !lvalue_p (init));
+                 TREE_TYPE (t) = eltype;
+                 layout_decl (t, 0);
+                 DECL_HAS_VALUE_EXPR_P (t) = 0;
+                 if (!processing_template_decl)
+                   {
+                     copy_linkage (t, decl);
+                     cp_finish_decl (t, init, /*constexpr*/false,
+                                     /*asm*/NULL_TREE, LOOKUP_NORMAL);
+                   }
+               }
+             continue;
+           }
+
+         unsigned HOST_WIDE_INT j = i;
+         if (pack != -1 && (unsigned) pack < i)
+           j = i + eltscnt - count;
          input_location = dloc;
-         tree init = get_tuple_decomp_init (decl, i);
+         tree init = get_tuple_decomp_init (decl, j);
          tree eltype = (init == error_mark_node ? error_mark_node
-                        : get_tuple_element_type (type, i));
+                        : get_tuple_element_type (type, j));
          input_location = sloc;
 
          if (VOID_TYPE_P (eltype))
            {
-             error ("%<std::tuple_element<%u, %T>::type%> is %<void%>",
-                    i, type);
+             error ("%<std::tuple_element<%wu, %T>::type%> is %<void%>",
+                    j, type);
              eltype = error_mark_node;
            }
          if (init == error_mark_node || eltype == error_mark_node)
@@ -10159,6 +10314,12 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
        goto error_out;
       else if (btype == NULL_TREE)
        {
+         if (pack == 0 && count == 1)
+           {
+             eltscnt = 0;
+             packv = make_tree_vec (2);
+             goto done;
+           }
          error_at (loc, "cannot decompose class type %qT without non-static "
                         "data members", type);
          goto error_out;
@@ -10170,7 +10331,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
          continue;
        else
          eltscnt++;
-      if (count != eltscnt)
+      if (pack != -1 ? count - 1 > eltscnt : count != eltscnt)
        goto cnt_mismatch;
       tree t = dexp;
       if (type != btype)
@@ -10179,6 +10340,7 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
                               /*nonnull*/false, tf_warning_or_error);
          type = btype;
        }
+      unsigned HOST_WIDE_INT j = 0;
       unsigned int i = 0;
       for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field))
        if (TREE_CODE (field) != FIELD_DECL
@@ -10191,6 +10353,32 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
                                                     NULL_TREE);
            if (REFERENCE_REF_P (tt))
              tt = TREE_OPERAND (tt, 0);
+           if (pack != -1 && j >= (unsigned) pack)
+             {
+               if (j == (unsigned) pack)
+                 {
+                   packv = make_tree_vec (eltscnt - count + 3);
+                   i++;
+                 }
+               if (j < (unsigned) pack + eltscnt - (count - 1))
+                 {
+                   tree t;
+                   TREE_VEC_ELT (packv, j + 3 - i) = t = copy_node (v[pack]);
+                   set_sb_pack_name (t, j + 1 - i);
+                   maybe_push_decl (t);
+                   TREE_TYPE (t) = TREE_TYPE (tt);
+                   layout_decl (t, 0);
+                   if (!processing_template_decl)
+                     {
+                       SET_DECL_VALUE_EXPR (t, tt);
+                       DECL_HAS_VALUE_EXPR_P (t) = 1;
+                     }
+                   else
+                     DECL_HAS_VALUE_EXPR_P (t) = 0;
+                   j++;
+                   continue;
+                 }
+             }
            TREE_TYPE (v[i]) = TREE_TYPE (tt);
            layout_decl (v[i], 0);
            if (!processing_template_decl)
@@ -10199,7 +10387,26 @@ cp_finish_decomp (tree decl, cp_decomp *decomp, bool 
test_p)
                DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
              }
            i++;
+           j++;
          }
+      if (pack != -1 && j == (unsigned) pack)
+       {
+         gcc_checking_assert (eltscnt == count - 1);
+         packv = make_tree_vec (2);
+       }
+    }
+ done:
+  if (packv)
+    {
+      gcc_checking_assert (pack != -1);
+      TREE_VEC_ELT (packv, 0) = decl;
+      TREE_VEC_ELT (packv, 1) = size_int (pack);
+      SET_DECL_VALUE_EXPR (v[pack], packv);
+      DECL_HAS_VALUE_EXPR_P (v[pack]) = 1;
+      DECL_IGNORED_P (v[pack]) = 1;
+      if (!processing_template_decl)
+       for (unsigned int i = 0; i < TREE_VEC_LENGTH (packv) - 2U; ++i)
+         pushdecl (TREE_VEC_ELT (packv, 2 + i));
     }
   if (processing_template_decl)
     {
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index a8c54c7514e3..743fd7498dec 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -14672,13 +14672,23 @@ cp_parser_range_for (cp_parser *parser, tree scope, 
tree init, tree range_decl,
          tree v = DECL_VALUE_EXPR (range_decl);
          /* For decomposition declaration get all of the corresponding
             declarations out of the way.  */
-         if (TREE_CODE (v) == ARRAY_REF
-             && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+         if ((TREE_CODE (v) == ARRAY_REF
+              && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+             || (TREE_CODE (v) == TREE_VEC
+                 && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0))))
            {
              tree d = range_decl;
-             range_decl = TREE_OPERAND (v, 0);
              decomp = &decomp_d;
-             decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
+             if (TREE_CODE (v) == ARRAY_REF)
+               {
+                 range_decl = TREE_OPERAND (v, 0);
+                 decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
+               }
+             else
+               {
+                 range_decl = TREE_VEC_ELT (v, 0);
+                 decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1;
+               }
              decomp->decl = d;
              bool seen_name_independent_decl = false;
              for (unsigned int i = 0; i < decomp->count;
@@ -16843,7 +16853,7 @@ cp_parser_simple_declaration (cp_parser* parser,
 }
 
 /* Helper of cp_parser_simple_declaration, parse a decomposition declaration.
-     decl-specifier-seq ref-qualifier [opt] [ identifier-list ]
+     decl-specifier-seq ref-qualifier [opt] [ sb-identifier-list ]
        initializer ;  */
 
 static tree
@@ -16856,21 +16866,45 @@ cp_parser_decomposition_declaration (cp_parser 
*parser,
   location_t loc = cp_lexer_peek_token (parser->lexer)->location;
   cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);
 
-  /* Parse the identifier-list.  */
+  /* Parse the sb-identifier-list.  */
   auto_vec<cp_expr, 10> v;
   bool attr_diagnosed = false;
   int first_attr = -1;
+  int pack = -1;
   unsigned int cnt = 0;
   if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
     while (true)
       {
+       if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
+         {
+           location_t elloc = cp_lexer_peek_token (parser->lexer)->location;
+           if (!processing_template_decl)
+             error_at (elloc, "structured binding pack outside of template");
+           else if (pack != -1)
+             error_at (elloc,
+                       "multiple packs in structured binding declaration");
+           else
+             {
+               if (keyword == RID_MAX
+                   && cxx_dialect >= cxx17
+                   && cxx_dialect < cxx26)
+                 pedwarn (elloc, OPT_Wc__26_extensions,
+                          "structured binding packs only available with "
+                          "%<-std=c++2c%> or %<-std=gnu++2c%>");
+               pack = cnt;
+             }
+           cp_lexer_consume_token (parser->lexer);
+         }
        cp_expr e = cp_parser_identifier (parser);
        if (e.get_value () == error_mark_node)
          break;
        tree attr = NULL_TREE;
        if (cp_next_tokens_can_be_std_attribute_p (parser))
          {
-           if (cxx_dialect >= cxx17 && cxx_dialect < cxx26 && !attr_diagnosed)
+           if (keyword == RID_MAX
+               && cxx_dialect >= cxx17
+               && cxx_dialect < cxx26
+               && !attr_diagnosed)
              {
                pedwarn (cp_lexer_peek_token (parser->lexer)->location,
                         OPT_Wc__26_extensions,
@@ -16931,7 +16965,7 @@ cp_parser_decomposition_declaration (cp_parser *parser,
                          &pushed_scope);
   tree orig_decl = decl;
 
-  unsigned int i;
+  unsigned int i, j;
   cp_expr e;
   cp_decl_specifier_seq decl_specs;
   clear_decl_specs (&decl_specs);
@@ -16939,6 +16973,7 @@ cp_parser_decomposition_declaration (cp_parser *parser,
   if (decl_specifiers->storage_class == sc_static)
     decl_specs.storage_class = sc_static;
   tree prev = decl;
+  j = 0;
   FOR_EACH_VEC_ELT (v, i, e)
     {
       if (i == 0)
@@ -16969,9 +17004,22 @@ cp_parser_decomposition_declaration (cp_parser *parser,
          prev = decl2;
          DECL_DECLARED_CONSTEXPR_P (decl2) = DECL_DECLARED_CONSTEXPR_P (decl);
          DECL_DECLARED_CONSTINIT_P (decl2) = DECL_DECLARED_CONSTINIT_P (decl);
+         if (j == (unsigned) pack)
+           {
+             tree dtype = cxx_make_type (DECLTYPE_TYPE);
+             DECLTYPE_TYPE_EXPR (dtype) = decl2;
+             DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (dtype) = 1;
+             SET_TYPE_STRUCTURAL_EQUALITY (dtype);
+             tree type = cxx_make_type (TYPE_PACK_EXPANSION);
+             PACK_EXPANSION_PATTERN (type) = dtype;
+             SET_TYPE_STRUCTURAL_EQUALITY (type);
+             PACK_EXPANSION_PARAMETER_PACKS (type) = decl2;
+             TREE_TYPE (decl2) = type;
+           }
        }
       if (elt_pushed_scope)
        pop_scope (elt_pushed_scope);
+      ++j;
     }
 
   if (v.is_empty ())
@@ -46300,6 +46348,14 @@ cp_convert_omp_range_for (tree &this_pre_body, tree 
&sl,
                  decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
                  decomp->decl = decl;
                }
+             else if (TREE_CODE (v) == TREE_VEC
+                      && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0)))
+               {
+                 d = TREE_VEC_ELT (v, 0);
+                 decomp = &decomp_d;
+                 decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1;
+                 decomp->decl = decl;
+               }
            }
          do_range_for_auto_deduction (d, init, decomp);
        }
@@ -46423,6 +46479,15 @@ cp_convert_omp_range_for (tree &this_pre_body, tree 
&sl,
          decomp->count = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
          decomp->decl = d;
        }
+      else if (TREE_CODE (v) == TREE_VEC
+              && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0)))
+       {
+         tree d = orig_decl;
+         orig_decl = TREE_VEC_ELT (v, 0);
+         decomp = &decomp_d;
+         decomp->count = tree_to_uhwi (TREE_VEC_ELT (v, 1)) + 1;
+         decomp->decl = d;
+       }
     }
 
   tree auto_node = type_uses_auto (TREE_TYPE (orig_decl));
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index acfeb8165921..b6b13edd03fc 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -13981,9 +13981,30 @@ tsubst_pack_expansion (tree t, tree args, 
tsubst_flags_t complain,
       else if (is_capture_proxy (parm_pack))
        {
          arg_pack = retrieve_local_specialization (parm_pack);
+         if (DECL_DECOMPOSITION_P (arg_pack))
+           {
+             orig_arg = arg_pack;
+             goto expand_sb_pack;
+           }
          if (DECL_PACK_P (arg_pack))
            arg_pack = NULL_TREE;
        }
+      else if (DECL_DECOMPOSITION_P (parm_pack))
+       {
+         orig_arg = retrieve_local_specialization (parm_pack);
+       expand_sb_pack:
+         gcc_assert (DECL_DECOMPOSITION_P (orig_arg));
+         if (TREE_TYPE (orig_arg) == error_mark_node)
+           return error_mark_node;
+         gcc_assert (DECL_HAS_VALUE_EXPR_P (orig_arg));
+         arg_pack = DECL_VALUE_EXPR (orig_arg);
+         tree vec = make_tree_vec (TREE_VEC_LENGTH (arg_pack) - 2);
+         if (TREE_VEC_LENGTH (vec))
+           memcpy (TREE_VEC_BEGIN (vec), &TREE_VEC_ELT (arg_pack, 2),
+                   TREE_VEC_LENGTH (vec) * sizeof (tree));
+         arg_pack = make_node (NONTYPE_ARGUMENT_PACK);
+         ARGUMENT_PACK_ARGS (arg_pack) = vec;
+       }
       else
         {
          int idx;
@@ -13996,7 +14017,8 @@ tsubst_pack_expansion (tree t, tree args, 
tsubst_flags_t complain,
            arg_pack = NULL_TREE;
         }
 
-      orig_arg = arg_pack;
+      if (orig_arg == NULL_TREE)
+       orig_arg = arg_pack;
       if (arg_pack && TREE_CODE (arg_pack) == ARGUMENT_PACK_SELECT)
        arg_pack = ARGUMENT_PACK_SELECT_FROM_PACK (arg_pack);
 
@@ -14011,8 +14033,8 @@ tsubst_pack_expansion (tree t, tree args, 
tsubst_flags_t complain,
 
       if (arg_pack)
         {
-          int my_len =
-            TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack));
+         int my_len
+           = TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg_pack));
 
          /* Don't bother trying to do a partial substitution with
             incomplete packs; we'll try again after deduction.  */
@@ -14176,8 +14198,8 @@ tsubst_pack_expansion (tree t, tree args, 
tsubst_flags_t complain,
 
           /* Update the corresponding argument.  */
           if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
-            TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx) =
-              TREE_TYPE (pack);
+           TREE_VEC_ELT (TREE_VEC_ELT (args, level -1 ), idx)
+             = TREE_TYPE (pack);
           else
             TREE_VEC_ELT (args, idx) = TREE_TYPE (pack);
         }
@@ -15921,7 +15943,10 @@ tsubst_decl (tree t, tree args, tsubst_flags_t 
complain,
            tsubst_flags_t tcomplain = complain;
            if (VAR_P (t))
              tcomplain |= tf_tst_ok;
-           type = tsubst (type, args, tcomplain, in_decl);
+           if (DECL_DECOMPOSITION_P (t) && DECL_PACK_P (t))
+             type = NULL_TREE;
+           else
+             type = tsubst (type, args, tcomplain, in_decl);
            /* Substituting the type might have recursively instantiated this
               same alias (c++/86171).  */
            if (use_spec_table && gen_tmpl && DECL_ALIAS_TEMPLATE_P (gen_tmpl)
@@ -15938,6 +15963,17 @@ tsubst_decl (tree t, tree args, tsubst_flags_t 
complain,
          {
            DECL_INITIALIZED_P (r) = 0;
            DECL_TEMPLATE_INSTANTIATED (r) = 0;
+           if (DECL_DECOMPOSITION_P (t) && DECL_PACK_P (t))
+             {
+               tree dtype = cxx_make_type (DECLTYPE_TYPE);
+               DECLTYPE_TYPE_EXPR (dtype) = r;
+               DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (dtype) = 1;
+               SET_TYPE_STRUCTURAL_EQUALITY (dtype);
+               type = cxx_make_type (TYPE_PACK_EXPANSION);
+               PACK_EXPANSION_PATTERN (type) = dtype;
+               SET_TYPE_STRUCTURAL_EQUALITY (type);
+               PACK_EXPANSION_PARAMETER_PACKS (type) = r;
+             }
            if (TREE_CODE (type) == FUNCTION_TYPE)
              {
                /* It may seem that this case cannot occur, since:
@@ -18555,13 +18591,17 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, 
tree &orig_declv,
       if (decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (decl))
        {
          tree v = DECL_VALUE_EXPR (decl);
-         if (TREE_CODE (v) == ARRAY_REF
-             && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+         if ((TREE_CODE (v) == ARRAY_REF
+              && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
+             || (TREE_CODE (v) == TREE_VEC
+                 && DECL_DECOMPOSITION_P (TREE_VEC_ELT (v, 0))))
            {
+             v = (TREE_CODE (v) == ARRAY_REF
+                  ? TREE_OPERAND (v, 0) : TREE_VEC_ELT (v, 0));
              cp_decomp decomp_d = { NULL_TREE, 0 };
-             tree d = tsubst_decl (TREE_OPERAND (v, 0), args, complain);
+             tree d = tsubst_decl (v, args, complain);
              maybe_push_decl (d);
-             d = tsubst_decomp_names (d, TREE_OPERAND (v, 0), args, complain,
+             d = tsubst_decomp_names (d, v, args, complain,
                                       in_decl, &decomp_d);
              decomp = true;
              if (d == error_mark_node)
@@ -21220,7 +21260,28 @@ tsubst_expr (tree t, tree args, tsubst_flags_t 
complain, tree in_decl)
          ++c_inhibit_evaluation_warnings;
          /* We only want to compute the number of arguments.  */
          if (PACK_EXPANSION_P (op))
-           expanded = tsubst_pack_expansion (op, args, complain, in_decl);
+           {
+             expanded = NULL_TREE;
+             if (DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (op)))
+               {
+                 tree d = PACK_EXPANSION_PATTERN (op);
+                 if (DECL_HAS_VALUE_EXPR_P (d))
+                   {
+                     d = DECL_VALUE_EXPR (d);
+                     if (TREE_CODE (d) == TREE_VEC)
+                       {
+                         tree b = TREE_VEC_ELT (d, 0);
+                         if (!type_dependent_expression_p_push (b))
+                           {
+                             expanded = void_node;
+                             len = TREE_VEC_LENGTH (d) - 2;
+                           }
+                       }
+                   }
+               }
+             if (!expanded)
+               expanded = tsubst_pack_expansion (op, args, complain, in_decl);
+           }
          else
            expanded = tsubst_template_args (ARGUMENT_PACK_ARGS (op),
                                             args, complain, in_decl);
@@ -29050,6 +29111,24 @@ value_dependent_expression_p (tree expression)
     case SIZEOF_EXPR:
       if (SIZEOF_EXPR_TYPE_P (expression))
        return dependent_type_p (TREE_TYPE (TREE_OPERAND (expression, 0)));
+      if (tree p = TREE_OPERAND (expression, 0))
+       if (PACK_EXPANSION_P (p)
+           && DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (p)))
+         {
+           tree d = PACK_EXPANSION_PATTERN (p);
+           if (DECL_HAS_VALUE_EXPR_P (d))
+             {
+               d = DECL_VALUE_EXPR (d);
+               /* [temp.dep.constexpr]/4:
+                  Expressions of the following form are value-dependent:
+                  sizeof ... ( identifier )
+                  unless the identifier is a structured binding pack whose
+                  initializer is not dependent.  */
+               if (TREE_CODE (d) == TREE_VEC
+                   && !type_dependent_expression_p (TREE_VEC_ELT (d, 0)))
+                 return false;
+             }
+         }
       /* FALLTHRU */
     case ALIGNOF_EXPR:
     case TYPEID_EXPR:
@@ -29563,6 +29642,22 @@ instantiation_dependent_r (tree *tp, int 
*walk_subtrees,
        tree op = TREE_OPERAND (*tp, 0);
        if (code == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (*tp))
          op = TREE_TYPE (op);
+       else if (code == SIZEOF_EXPR
+                && PACK_EXPANSION_P (op)
+                && DECL_DECOMPOSITION_P (PACK_EXPANSION_PATTERN (op)))
+         {
+           tree d = PACK_EXPANSION_PATTERN (op);
+           if (DECL_HAS_VALUE_EXPR_P (d))
+             {
+               d = DECL_VALUE_EXPR (d);
+               if (TREE_CODE (d) == TREE_VEC
+                   && !type_dependent_expression_p (TREE_VEC_ELT (d, 0)))
+                 {
+                   *walk_subtrees = 0;
+                   return NULL_TREE;
+                 }
+             }
+         }
        if (TYPE_P (op))
          {
            if (dependent_type_p (op))
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp13.C 
b/gcc/testsuite/g++.dg/cpp26/decomp13.C
new file mode 100644
index 000000000000..d01590ffe1c5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp13.C
@@ -0,0 +1,52 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+namespace std {
+  template<typename T> struct tuple_size;
+  template<int, typename> struct tuple_element;
+}
+
+struct S { int a, b, c, d; };
+struct T {
+  int a[5];
+  template <int I> int &get () { return a[I]; }
+};
+
+template<> struct std::tuple_size<T> { static const int value = 5; };
+template<int I> struct std::tuple_element<I,T> { using type = int; };
+
+template <int N>
+void
+foo ()
+{
+  auto [a, ...b, c] = S ();            // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  auto [...d] = S ();                  // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  auto [...e, f, ...g, h] = S ();      // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-error "multiple packs in 
structured binding declaration" "" { target *-*-* } .-2 }
+  auto [i, j, k, l, ...m, n] = S ();   // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-error "6 names provided for 
structured binding" "" { target *-*-* } .-2 }
+                                       // { dg-message "while 'S' decomposes 
into 4 elements" "" { target *-*-* } .-3 }
+  auto [o, ...p, q, r, s] = S ();      // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  auto [t, u, v, w, x, ...y, z] = T ();        // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-error "7 names provided for 
structured binding" "" { target *-*-* } .-2 }
+                                       // { dg-message "while 'T' decomposes 
into 5 elements" "" { target *-*-* } .-3 }
+  int aa[] = { 1, 2, 3 };
+  const auto & [ab, ...ac, ad, ae, af] = aa; // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-error "5 names provided for 
structured binding" "" { target *-*-* } .-2 }
+                                       // { dg-message "while 'const int 
\\\[3\\\]' decomposes into 3 elements" "" { target *-*-* } .-3 }
+}
+
+void
+bar ()
+{
+  auto [a, ...b, c, d] = S ();         // { dg-error "structured binding pack 
outside of template" }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp14.C 
b/gcc/testsuite/g++.dg/cpp26/decomp14.C
new file mode 100644
index 000000000000..f626ec9ac679
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp14.C
@@ -0,0 +1,474 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct S {
+  int a; long long b; short c;
+  explicit operator bool () const noexcept { return true; }
+};
+namespace std {
+  template <typename T> struct tuple_size;
+  template <int, typename> struct tuple_element;
+}
+struct T {
+  short c; int a; long long b;
+  template <int I>
+  typename std::tuple_element<I, T>::type &get ();
+  template <int I>
+  typename std::tuple_element<I, const T>::type &get () const;
+  explicit operator bool () const noexcept { return false; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, T> { typedef int type; };
+template <>
+struct std::tuple_element<1, T> { typedef long long type; };
+template <>
+struct std::tuple_element<2, T> { typedef short type; };
+template <>
+std::tuple_element<0, T>::type &T::get <0> () { return a; }
+template <>
+std::tuple_element<1, T>::type &T::get <1> () { return b; }
+template <>
+std::tuple_element<2, T>::type &T::get <2> () { return c; }
+template <>
+struct std::tuple_size<const T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, const T> { typedef const int type; };
+template <>
+struct std::tuple_element<1, const T> { typedef const long long type; };
+template <>
+struct std::tuple_element<2, const T> { typedef const short type; };
+template <>
+std::tuple_element<0, const T>::type &T::get <0> () const { return a; }
+template <>
+std::tuple_element<1, const T>::type &T::get <1> () const { return b; }
+template <>
+std::tuple_element<2, const T>::type &T::get <2> () const { return c; }
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+int
+sum ()
+{
+  return 0;
+}
+
+template <typename T, typename ...A>
+T
+sum (T x, A... y)
+{
+  return x + sum (y...);
+}
+
+template <typename T>
+T
+square (T x)
+{
+  return x * x;
+}
+
+template <typename T>
+T &
+ref (T &x)
+{
+  return x;
+}
+
+using size_t = decltype (sizeof 0);
+
+template <int N>
+size_t
+foo ()
+{
+  S s = S { 1, 2, 3 };
+  auto [sa, sb, sc] = S { 1, 2, 3 };   // { dg-warning "structured bindings 
only available with" "" { target c++14_down } }
+  static_assert (same_type <decltype (sa), int>::value, "");
+  static_assert (same_type <decltype (sb), long long>::value, "");
+  static_assert (same_type <decltype (sc), short>::value, "");
+  auto [sd, ...se] = S { 1, 2, 3 };    // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  constexpr size_t ses = sizeof... (se);
+  static_assert (sizeof... (se) == 2, "");
+  static_assert (same_type <decltype (sd), int>::value, "");
+  static_assert (same_type <decltype (se...[0]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (se...[1]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  const auto & [...sf [[]], sg] = s;   // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (sf) == 2, "");
+  static_assert (same_type <decltype (sf...[0]), const int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (sf...[1]), const long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (sg), const short>::value, "");
+  auto [sh, si, sj [[]], ...sk] = S { 1, 2, 3 };// { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (sk) == 0, "");
+  static_assert (same_type <decltype (sh), int>::value, "");
+  static_assert (same_type <decltype (si), long long>::value, "");
+  static_assert (same_type <decltype (sj), short>::value, "");
+  auto && [sl, ...sm [[maybe_unused]], sn] = s; // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (sm) == 1, "");
+  static_assert (same_type <decltype (sl), int>::value, "");
+  static_assert (same_type <decltype (sm...[0]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (sn), short>::value, "");
+  auto [...so] = S { 1, 2, 3 };                // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (so) == 3, "");
+  static_assert (same_type <decltype (so...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (so...[1]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (so...[2]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...sp, sq, sr, ss [[maybe_unused]]] = S { 1, 2, 3 };// { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (sp) == 0, "");
+  static_assert (same_type <decltype (sq), int>::value, "");
+  static_assert (same_type <decltype (sr), long long>::value, "");
+  static_assert (same_type <decltype (ss), short>::value, "");
+  auto [st, ...su, sv, sw] = S { 1, 2, 3 };// { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (su) == 0, "");
+  static_assert (same_type <decltype (st), int>::value, "");
+  static_assert (same_type <decltype (sv), long long>::value, "");
+  static_assert (same_type <decltype (sw), short>::value, "");
+  if (sa != 1 || sb != 2 || sc != 3
+      || sd != 1 || se...[0] != 2 || se...[1] != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || sf...[0] != 1 || sf...[1] != 2 || sg != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || sh != 1 || si != 2 || sj != 3
+      || sl != 1 || sm...[0] != 2 || sn != 3           // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || so...[0] != 1 || so...[1] != 2 || so...[2] != 3// { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || sq != 1 || sr != 2 || ss != 3
+      || st != 1 || sv != 2 || sw != 3
+      || sum (se...) != 5
+      || sum <decltype (se)...> (se...) != 5
+      || sum (square (square (se))...) != 97
+      || sum (sf...) != 3
+      || sum (sk...) != 0
+      || sum (sm...) != 2
+      || sum (so...) != 6
+      || sum <decltype (so)...> (so...) != 6
+      || sum (square (so)...) != 14
+      || sum (sp...) != 0
+      || sum (su...) != 0
+      || (se + ...) != 5               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + sf) != 3               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + sk) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (sm + ... + 0) != 2           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (so + ...) != 6               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (sp + ... + 0) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + su) != 0)          // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+    __builtin_abort ();
+  S s2[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
+  int i = 0;
+  for (auto [sx, ...sy [[]]] : s2)     // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+      static_assert (sizeof... (sy) == 2, "");
+      static_assert (same_type <decltype (sx), int>::value, "");
+      static_assert (same_type <decltype (sy...[0]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sy...[1]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (sx != i * 3 + 1 || sum (sy...) != i * 6 + 5)
+       __builtin_abort ();
+      auto fn1 = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; 
// { dg-warning "captured structured bindings are" "" { target c++17_down } }
+      fn1 ();
+      auto fn2 = [&sy..., &i] () { if (sum (sy...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { 
target c++17_down } }
+      fn2 ();
+      auto fn3 = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn3 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn4 = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn4 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn5 = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; 
// { dg-warning "captured structured bindings are" "" { target c++17_down } }
+      fn5 ();
+      auto fn6 = [sy..., i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort 
(); }; // { dg-warning "captured structured bindings are" "" { target 
c++17_down } }
+      fn6 ();
+      auto fn7 = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn7 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn8 = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 
2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { 
dg-warning "pack init-capture only available with" "" { target c++17_down } }
+      fn8 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn9 = [&] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) 
__builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings 
are" "" { target c++17_down } }
+      fn9 ();
+      auto fn10 = [&sy..., &i] () { auto fn = [&] () { if (sum (sy...) != i * 
6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured 
bindings are" "" { target c++17_down } }
+      fn10 ();
+      auto fn11 = [&] () { auto fn = [&...sy2 = sy, &i] () { if (sum (sy2...) 
!= i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack 
init-capture only available with" "" { target c++17_down } }
+      fn11 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      auto fn12 = [&sy..., &i] () { auto fn = [&...sy3 = ref (sy), &i] () { if 
(sum (sy3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning 
"pack init-capture only available with" "" { target c++17_down } }
+      fn12 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      auto fn13 = [=] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) 
__builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings 
are" "" { target c++17_down } }
+      fn13 ();
+      auto fn14 = [sy..., i] () { auto fn = [=] () { if (sum (sy...) != i * 6 
+ 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured 
bindings are" "" { target c++17_down } }
+      fn14 ();
+      auto fn15 = [=] () { auto fn = [...sy2 = sy, i] () { if (sum (sy2...) != 
i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture 
only available with" "" { target c++17_down } }
+      fn15 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      auto fn16 = [&sy..., &i] () { auto fn = [...sy3 = square (sy), i] () { 
if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) 
__builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only 
available with" "" { target c++17_down } }
+      fn16 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      ++i;
+    }
+  i = 0;
+  for (auto [...sz] : s2)              // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (sz) == 3, "");
+      static_assert (same_type <decltype (sz...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sz...[1]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sz...[2]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (sum (sz...) != i * 9 + 6)
+       __builtin_abort ();
+      auto fn = [=] () { if (sum (sz...) != i * 9 + 6) __builtin_abort (); };  
// { dg-warning "captured structured bindings are" "" { target c++17_down } }
+      fn ();
+      ++i;
+    }
+  if (auto [...sx, sy] = s)            // { dg-warning "structured bindings in 
conditions only available with" "" { target c++23_down } }
+    {
+      static_assert (sizeof... (sx) == 2, "");
+      static_assert (same_type <decltype (sx...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sx...[1]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sy), short>::value, "");
+      if (sum (sx...) != 3 || sy != 3)
+       __builtin_abort ();
+    }
+  else
+    __builtin_abort ();
+  T t = T { 3, 1, 2 };
+  auto [ta, tb, tc] = T { 3, 1, 2 };   // { dg-warning "structured bindings 
only available with" "" { target c++14_down } }
+  static_assert (same_type <decltype (ta), int>::value, "");
+  static_assert (same_type <decltype (tb), long long>::value, "");
+  static_assert (same_type <decltype (tc), short>::value, "");
+  auto [td [[maybe_unused]], ...te] = T { 3, 1, 2 }; // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (te) == 2, "");
+  static_assert (same_type <decltype (td), int>::value, "");
+  static_assert (same_type <decltype (te...[0]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (te...[1]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...tf [[maybe_unused]], tg] = T { 3, 1, 2 }; // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (tf) == 2, "");
+  static_assert (same_type <decltype (tf...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (tf...[1]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (tg), short>::value, "");
+  const auto & [th, ti, tj, ...tk] = t;        // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (tk) == 0, "");
+  static_assert (same_type <decltype (th), const int>::value, "");
+  static_assert (same_type <decltype (ti), const long long>::value, "");
+  static_assert (same_type <decltype (tj), const short>::value, "");
+  auto [tl [[]], ...tm [[]], tn [[]]] = T { 3, 1, 2 }; // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (tm) == 1, "");
+  static_assert (same_type <decltype (tl), int>::value, "");
+  static_assert (same_type <decltype (tm...[0]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (tn), short>::value, "");
+  auto && [...to] = t;                 // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (to) == 3, "");
+  static_assert (same_type <decltype (to...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (to...[1]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (to...[2]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...tp, tq [[]], tr, ts] = T { 3, 1, 2 };// { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (tp) == 0, "");
+  static_assert (same_type <decltype (tq), int>::value, "");
+  static_assert (same_type <decltype (tr), long long>::value, "");
+  static_assert (same_type <decltype (ts), short>::value, "");
+  auto [tt, ...tu [[]], tv, tw] = T { 3, 1, 2 };// { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (tu) == 0, "");
+  static_assert (same_type <decltype (tt), int>::value, "");
+  static_assert (same_type <decltype (tv), long long>::value, "");
+  static_assert (same_type <decltype (tw), short>::value, "");
+  if (ta != 1 || tb != 2 || tc != 3
+      || td != 1 || te...[0] != 2 || te...[1] != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || tf...[0] != 1 || tf...[1] != 2 || tg != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || th != 1 || ti != 2 || tj != 3
+      || tl != 1 || tm...[0] != 2 || tn != 3           // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || to...[0] != 1 || to...[1] != 2 || to...[2] != 3// { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || tq != 1 || tr != 2 || ts != 3
+      || tt != 1 || tv != 2 || tw != 3
+      || sum (te...) != 5
+      || sum <decltype (te)...> (te...) != 5
+      || sum (square (square (te))...) != 97
+      || sum (tf...) != 3
+      || sum (tk...) != 0
+      || sum (tm...) != 2
+      || sum (to...) != 6
+      || sum <decltype (to)...> (to...) != 6
+      || sum (square (to)...) != 14
+      || sum (tp...) != 0
+      || sum (tu...) != 0
+      || (te + ...) != 5               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + tf) != 3               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + tk) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (tm + ... + 0) != 2           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (to + ...) != 6               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (tp + ... + 0) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + tu) != 0)          // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+    __builtin_abort ();
+  T t2[] = { { 3, 1, 2 }, { 6, 4, 5 }, { 9, 7, 8 } };
+  i = 0;
+  for (auto [tx, ...ty] : t2)          // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (ty) == 2, "");
+      static_assert (same_type <decltype (tx), int>::value, "");
+      static_assert (same_type <decltype (ty...[0]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (ty...[1]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (tx != i * 3 + 1 || sum (ty...) != i * 6 + 5)
+       __builtin_abort ();
+      auto fn1 = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+      fn1 ();
+      auto fn2 = [&ty..., &i] () { if (sum (ty...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { 
target c++17_down } }
+      fn2 ();
+      auto fn3 = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn3 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn4 = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn4 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn5 = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+      fn5 ();
+      auto fn6 = [ty..., i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort 
(); }; // { dg-warning "captured structured bindings are" "" { target 
c++17_down } }
+      fn6 ();
+      auto fn7 = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn7 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn8 = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 
2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { 
dg-warning "pack init-capture only available with" "" { target c++17_down } }
+      fn8 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn9 = [&] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) 
__builtin_abort (); }; fn (); };
+      fn9 ();
+      auto fn10 = [&ty..., &i] () { auto fn = [&] () { if (sum (ty...) != i * 
6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured 
bindings are" "" { target c++17_down } }
+      fn10 ();
+      auto fn11 = [&] () { auto fn = [&...ty2 = ty, &i] () { if (sum (ty2...) 
!= i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack 
init-capture only available with" "" { target c++17_down } }
+      fn11 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn12 = [&ty..., &i] () { auto fn = [&...ty3 = ref (ty), &i] () { if 
(sum (ty3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning 
"pack init-capture only available with" "" { target c++17_down } }
+      fn12 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      auto fn13 = [=] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) 
__builtin_abort (); }; fn (); };
+      fn13 ();
+      auto fn14 = [ty..., i] () { auto fn = [=] () { if (sum (ty...) != i * 6 
+ 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured 
bindings are" "" { target c++17_down } }
+      fn14 ();
+      auto fn15 = [=] () { auto fn = [...ty2 = ty, i] () { if (sum (ty2...) != 
i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture 
only available with" "" { target c++17_down } }
+      fn15 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn16 = [&ty..., &i] () { auto fn = [...ty3 = square (ty), i] () { 
if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) 
__builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only 
available with" "" { target c++17_down } }
+      fn16 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      ++i;
+    }
+  i = 0;
+  for (auto [...tz] : t2)              // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (tz) == 3, "");
+      static_assert (same_type <decltype (tz...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (tz...[1]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (tz...[2]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (sum (tz...) != i * 9 + 6)
+       __builtin_abort ();
+      auto fn = [=] () { if (sum (tz...) != i * 9 + 6) __builtin_abort (); };
+      fn ();
+      ++i;
+    }
+  if (auto [...tx [[maybe_unused]], ty] = t) // { dg-warning "structured 
bindings in conditions only available with" "" { target c++23_down } }
+    __builtin_abort ();
+  else
+    {
+      static_assert (sizeof... (tx) == 2, "");
+      static_assert (same_type <decltype (tx...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (tx...[1]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (ty), short>::value, "");
+      if (sum (tx...) != 3 || ty != 3)
+       __builtin_abort ();
+    }
+  int a[3] = { 1, 2, 3 };
+  auto [aa, ab, ac] = a;       // { dg-warning "structured bindings only 
available with" "" { target c++14_down } }
+  static_assert (same_type <decltype (aa), int>::value, "");
+  static_assert (same_type <decltype (ab), int>::value, "");
+  static_assert (same_type <decltype (ac), int>::value, "");
+  auto [ad [[maybe_unused]], ...ae [[maybe_unused]]] = a; // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+                               // { dg-warning "structured bindings with 
attributed identifiers only available with" "" { target { c++17 && c++23_down } 
} .-2 }
+  static_assert (sizeof... (ae) == 2, "");
+  static_assert (same_type <decltype (ad), int>::value, "");
+  static_assert (same_type <decltype (ae...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ae...[1]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...af, ag] = a;                // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (af) == 2, "");
+  static_assert (same_type <decltype (af...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (af...[1]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ag), int>::value, "");
+  auto [ah, ai [[]], aj, ...ak [[]]] = a; // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+                               // { dg-warning "structured bindings with 
attributed identifiers only available with" "" { target { c++17 && c++23_down } 
} .-2 }
+  static_assert (sizeof... (ak) == 0, "");
+  static_assert (same_type <decltype (ah), int>::value, "");
+  static_assert (same_type <decltype (ai), int>::value, "");
+  static_assert (same_type <decltype (aj), int>::value, "");
+  auto [al, ...am [[]], an] = a;// { dg-warning "structured binding packs only 
available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+                               // { dg-warning "structured bindings with 
attributed identifiers only available with" "" { target { c++17 && c++23_down } 
} .-2 }
+  static_assert (sizeof... (am) == 1, "");
+  static_assert (same_type <decltype (al), int>::value, "");
+  static_assert (same_type <decltype (am...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (an), int>::value, "");
+  const auto &[...ao] = a;     // { dg-warning "structured binding packs only 
available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (ao) == 3, "");
+  static_assert (same_type <decltype (ao...[0]), const int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ao...[1]), const int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ao...[2]), const int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto &&[...ap, aq, ar [[]], as] = a;// { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+                               // { dg-warning "structured bindings with 
attributed identifiers only available with" "" { target { c++17 && c++23_down } 
} .-2 }
+  static_assert (sizeof... (ap) == 0, "");
+  static_assert (same_type <decltype (aq), int>::value, "");
+  static_assert (same_type <decltype (ar), int>::value, "");
+  static_assert (same_type <decltype (as), int>::value, "");
+  auto [at, ...au, av, aw] = a;        // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (au) == 0, "");
+  static_assert (same_type <decltype (at), int>::value, "");
+  static_assert (same_type <decltype (av), int>::value, "");
+  static_assert (same_type <decltype (aw), int>::value, "");
+  if (aa != 1 || ab != 2 || ac != 3
+      || ad != 1 || ae...[0] != 2 || ae...[1] != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || af...[0] != 1 || af...[1] != 2 || ag != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || ah != 1 || ai != 2 || aj != 3
+      || al != 1 || am...[0] != 2 || an != 3           // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || ao...[0] != 1 || ao...[1] != 2 || ao...[2] != 3// { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || aq != 1 || ar != 2 || as != 3
+      || at != 1 || av != 2 || aw != 3
+      || sum (ae...) != 5
+      || sum <decltype (ae)...> (ae...) != 5
+      || sum (square (square (ae))...) != 97
+      || sum (af...) != 3
+      || sum (ak...) != 0
+      || sum (am...) != 2
+      || sum (ao...) != 6
+      || sum <decltype (ao)...> (ao...) != 6
+      || sum (square (ao)...) != 14
+      || sum (ap...) != 0
+      || sum (au...) != 0
+      || (ae + ...) != 5               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + af) != 3               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + ak) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (am + ... + 0) != 2           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (ao + ...) != 6               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (ap + ... + 0) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + au) != 0)          // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+    __builtin_abort ();
+  return ses;
+}
+
+int
+main ()
+{
+  if (foo <0> () != 2)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp15.C 
b/gcc/testsuite/g++.dg/cpp26/decomp15.C
new file mode 100644
index 000000000000..9bb55b34c949
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp15.C
@@ -0,0 +1,474 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct S {
+  int a; long long b; short c;
+  explicit operator bool () const noexcept { return true; }
+};
+namespace std {
+  template <typename T> struct tuple_size;
+  template <int, typename> struct tuple_element;
+}
+struct T {
+  short c; int a; long long b;
+  template <int I>
+  typename std::tuple_element<I, T>::type &get ();
+  template <int I>
+  typename std::tuple_element<I, const T>::type &get () const;
+  explicit operator bool () const noexcept { return false; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, T> { typedef int type; };
+template <>
+struct std::tuple_element<1, T> { typedef long long type; };
+template <>
+struct std::tuple_element<2, T> { typedef short type; };
+template <>
+std::tuple_element<0, T>::type &T::get <0> () { return a; }
+template <>
+std::tuple_element<1, T>::type &T::get <1> () { return b; }
+template <>
+std::tuple_element<2, T>::type &T::get <2> () { return c; }
+template <>
+struct std::tuple_size<const T> { static constexpr int value = 3; };
+template <>
+struct std::tuple_element<0, const T> { typedef const int type; };
+template <>
+struct std::tuple_element<1, const T> { typedef const long long type; };
+template <>
+struct std::tuple_element<2, const T> { typedef const short type; };
+template <>
+std::tuple_element<0, const T>::type &T::get <0> () const { return a; }
+template <>
+std::tuple_element<1, const T>::type &T::get <1> () const { return b; }
+template <>
+std::tuple_element<2, const T>::type &T::get <2> () const { return c; }
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+int
+sum ()
+{
+  return 0;
+}
+
+template <typename T, typename ...A>
+T
+sum (T x, A... y)
+{
+  return x + sum (y...);
+}
+
+template <typename T>
+T
+square (T x)
+{
+  return x * x;
+}
+
+template <typename T>
+T &
+ref (T &x)
+{
+  return x;
+}
+
+using size_t = decltype (sizeof 0);
+
+template <typename S, typename T, typename U>
+size_t
+foo ()
+{
+  S s = S { 1, 2, 3 };
+  auto [sa, sb, sc] = S { 1, 2, 3 };   // { dg-warning "structured bindings 
only available with" "" { target c++14_down } }
+  static_assert (same_type <decltype (sa), int>::value, "");
+  static_assert (same_type <decltype (sb), long long>::value, "");
+  static_assert (same_type <decltype (sc), short>::value, "");
+  auto [sd, ...se] = S { 1, 2, 3 };    // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (se) == 2, "");
+  static_assert (same_type <decltype (sd), int>::value, "");
+  static_assert (same_type <decltype (se...[0]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (se...[1]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  const auto & [...sf [[]], sg] = s;   // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (sf) == 2, "");
+  static_assert (same_type <decltype (sf...[0]), const int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (sf...[1]), const long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (sg), const short>::value, "");
+  auto [sh, si, sj [[]], ...sk] = S { 1, 2, 3 };// { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (sk) == 0, "");
+  static_assert (same_type <decltype (sh), int>::value, "");
+  static_assert (same_type <decltype (si), long long>::value, "");
+  static_assert (same_type <decltype (sj), short>::value, "");
+  auto && [sl, ...sm [[maybe_unused]], sn] = s; // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (sm) == 1, "");
+  static_assert (same_type <decltype (sl), int>::value, "");
+  static_assert (same_type <decltype (sm...[0]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (sn), short>::value, "");
+  auto [...so] = S { 1, 2, 3 };                // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (so) == 3, "");
+  static_assert (same_type <decltype (so...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (so...[1]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (so...[2]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...sp, sq, sr, ss [[maybe_unused]]] = S { 1, 2, 3 };// { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (sp) == 0, "");
+  static_assert (same_type <decltype (sq), int>::value, "");
+  static_assert (same_type <decltype (sr), long long>::value, "");
+  static_assert (same_type <decltype (ss), short>::value, "");
+  auto [st, ...su, sv, sw] = S { 1, 2, 3 };// { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (su) == 0, "");
+  static_assert (same_type <decltype (st), int>::value, "");
+  static_assert (same_type <decltype (sv), long long>::value, "");
+  static_assert (same_type <decltype (sw), short>::value, "");
+  if (sa != 1 || sb != 2 || sc != 3
+      || sd != 1 || se...[0] != 2 || se...[1] != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || sf...[0] != 1 || sf...[1] != 2 || sg != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || sh != 1 || si != 2 || sj != 3
+      || sl != 1 || sm...[0] != 2 || sn != 3           // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || so...[0] != 1 || so...[1] != 2 || so...[2] != 3// { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || sq != 1 || sr != 2 || ss != 3
+      || st != 1 || sv != 2 || sw != 3
+      || sum (se...) != 5
+      || sum <decltype (se)...> (se...) != 5
+      || sum (square (square (se))...) != 97
+      || sum (sf...) != 3
+      || sum (sk...) != 0
+      || sum (sm...) != 2
+      || sum (so...) != 6
+      || sum <decltype (so)...> (so...) != 6
+      || sum (square (so)...) != 14
+      || sum (sp...) != 0
+      || sum (su...) != 0
+      || (se + ...) != 5               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + sf) != 3               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + sk) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (sm + ... + 0) != 2           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (so + ...) != 6               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (sp + ... + 0) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + su) != 0)          // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+    __builtin_abort ();
+  S s2[] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
+  int i = 0;
+  for (auto [sx, ...sy [[]]] : s2)     // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+      static_assert (sizeof... (sy) == 2, "");
+      static_assert (same_type <decltype (sx), int>::value, "");
+      static_assert (same_type <decltype (sy...[0]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sy...[1]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (sx != i * 3 + 1 || sum (sy...) != i * 6 + 5)
+       __builtin_abort ();
+      auto fn1 = [&] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; 
// { dg-warning "captured structured bindings are" "" { target c++17_down } }
+      fn1 ();
+      auto fn2 = [&sy..., &i] () { if (sum (sy...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { 
target c++17_down } }
+      fn2 ();
+      auto fn3 = [&...sy2 = sy, &i] () { if (sum (sy2...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn3 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn4 = [&...sy3 = ref (sy), &i] () { if (sum (sy3...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn4 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn5 = [=] () { if (sum (sy...) != i * 6 + 5) __builtin_abort (); }; 
// { dg-warning "captured structured bindings are" "" { target c++17_down } }
+      fn5 ();
+      auto fn6 = [sy..., i] () { if (sum (sy...) != i * 6 + 5) __builtin_abort 
(); }; // { dg-warning "captured structured bindings are" "" { target 
c++17_down } }
+      fn6 ();
+      auto fn7 = [...sy2 = sy, i] () { if (sum (sy2...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn7 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn8 = [...sy3 = square (sy), i] () { if (sum (sy3...) != (i * 3 + 
2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { 
dg-warning "pack init-capture only available with" "" { target c++17_down } }
+      fn8 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn9 = [&] () { auto fn = [&] () { if (sum (sy...) != i * 6 + 5) 
__builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings 
are" "" { target c++17_down } }
+      fn9 ();
+      auto fn10 = [&sy..., &i] () { auto fn = [&] () { if (sum (sy...) != i * 
6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured 
bindings are" "" { target c++17_down } }
+      fn10 ();
+      auto fn11 = [&] () { auto fn = [&...sy2 = sy, &i] () { if (sum (sy2...) 
!= i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack 
init-capture only available with" "" { target c++17_down } }
+      fn11 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      auto fn12 = [&sy..., &i] () { auto fn = [&...sy3 = ref (sy), &i] () { if 
(sum (sy3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning 
"pack init-capture only available with" "" { target c++17_down } }
+      fn12 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      auto fn13 = [=] () { auto fn = [=] () { if (sum (sy...) != i * 6 + 5) 
__builtin_abort (); }; fn (); }; // { dg-warning "captured structured bindings 
are" "" { target c++17_down } }
+      fn13 ();
+      auto fn14 = [sy..., i] () { auto fn = [=] () { if (sum (sy...) != i * 6 
+ 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured 
bindings are" "" { target c++17_down } }
+      fn14 ();
+      auto fn15 = [=] () { auto fn = [...sy2 = sy, i] () { if (sum (sy2...) != 
i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture 
only available with" "" { target c++17_down } }
+      fn15 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      auto fn16 = [&sy..., &i] () { auto fn = [...sy3 = square (sy), i] () { 
if (sum (sy3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) 
__builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only 
available with" "" { target c++17_down } }
+      fn16 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      ++i;
+    }
+  i = 0;
+  for (auto [...sz] : s2)              // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (sz) == 3, "");
+      static_assert (same_type <decltype (sz...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sz...[1]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sz...[2]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (sum (sz...) != i * 9 + 6)
+       __builtin_abort ();
+      auto fn = [=] () { if (sum (sz...) != i * 9 + 6) __builtin_abort (); };  
// { dg-warning "captured structured bindings are" "" { target c++17_down } }
+      fn ();
+      ++i;
+    }
+  if (auto [...sx, sy] = s)            // { dg-warning "structured bindings in 
conditions only available with" "" { target c++23_down } }
+    {
+      static_assert (sizeof... (sx) == 2, "");
+      static_assert (same_type <decltype (sx...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sx...[1]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (sy), short>::value, "");
+      if (sum (sx...) != 3 || sy != 3)
+       __builtin_abort ();
+    }
+  else
+    __builtin_abort ();
+  T t = T { 3, 1, 2 };
+  auto [ta, tb, tc] = T { 3, 1, 2 };   // { dg-warning "structured bindings 
only available with" "" { target c++14_down } }
+  static_assert (same_type <decltype (ta), int>::value, "");
+  static_assert (same_type <decltype (tb), long long>::value, "");
+  static_assert (same_type <decltype (tc), short>::value, "");
+  auto [td [[maybe_unused]], ...te] = T { 3, 1, 2 }; // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (te) == 2, "");
+  static_assert (same_type <decltype (td), int>::value, "");
+  static_assert (same_type <decltype (te...[0]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (te...[1]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...tf [[maybe_unused]], tg] = T { 3, 1, 2 }; // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (tf) == 2, "");
+  static_assert (same_type <decltype (tf...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (tf...[1]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (tg), short>::value, "");
+  const auto & [th, ti, tj, ...tk] = t;        // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (tk) == 0, "");
+  static_assert (same_type <decltype (th), const int>::value, "");
+  static_assert (same_type <decltype (ti), const long long>::value, "");
+  static_assert (same_type <decltype (tj), const short>::value, "");
+  auto [tl [[]], ...tm [[]], tn [[]]] = T { 3, 1, 2 }; // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (tm) == 1, "");
+  static_assert (same_type <decltype (tl), int>::value, "");
+  static_assert (same_type <decltype (tm...[0]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (tn), short>::value, "");
+  auto && [...to] = t;                 // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (to) == 3, "");
+  constexpr size_t tos = sizeof... (to);
+  static_assert (same_type <decltype (to...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (to...[1]), long long>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (to...[2]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...tp, tq [[]], tr, ts] = T { 3, 1, 2 };// { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (tp) == 0, "");
+  static_assert (same_type <decltype (tq), int>::value, "");
+  static_assert (same_type <decltype (tr), long long>::value, "");
+  static_assert (same_type <decltype (ts), short>::value, "");
+  auto [tt, ...tu [[]], tv, tw] = T { 3, 1, 2 };// { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured bindings 
with attributed identifiers only available with" "" { target { c++17 && 
c++23_down } } .-2 }
+  static_assert (sizeof... (tu) == 0, "");
+  static_assert (same_type <decltype (tt), int>::value, "");
+  static_assert (same_type <decltype (tv), long long>::value, "");
+  static_assert (same_type <decltype (tw), short>::value, "");
+  if (ta != 1 || tb != 2 || tc != 3
+      || td != 1 || te...[0] != 2 || te...[1] != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || tf...[0] != 1 || tf...[1] != 2 || tg != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || th != 1 || ti != 2 || tj != 3
+      || tl != 1 || tm...[0] != 2 || tn != 3           // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || to...[0] != 1 || to...[1] != 2 || to...[2] != 3// { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || tq != 1 || tr != 2 || ts != 3
+      || tt != 1 || tv != 2 || tw != 3
+      || sum (te...) != 5
+      || sum <decltype (te)...> (te...) != 5
+      || sum (square (square (te))...) != 97
+      || sum (tf...) != 3
+      || sum (tk...) != 0
+      || sum (tm...) != 2
+      || sum (to...) != 6
+      || sum <decltype (to)...> (to...) != 6
+      || sum (square (to)...) != 14
+      || sum (tp...) != 0
+      || sum (tu...) != 0
+      || (te + ...) != 5               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + tf) != 3               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + tk) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (tm + ... + 0) != 2           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (to + ...) != 6               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (tp + ... + 0) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + tu) != 0)          // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+    __builtin_abort ();
+  T t2[] = { { 3, 1, 2 }, { 6, 4, 5 }, { 9, 7, 8 } };
+  i = 0;
+  for (auto [tx, ...ty] : t2)          // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (ty) == 2, "");
+      static_assert (same_type <decltype (tx), int>::value, "");
+      static_assert (same_type <decltype (ty...[0]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (ty...[1]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (tx != i * 3 + 1 || sum (ty...) != i * 6 + 5)
+       __builtin_abort ();
+      auto fn1 = [&] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+      fn1 ();
+      auto fn2 = [&ty..., &i] () { if (sum (ty...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "captured structured bindings are" "" { 
target c++17_down } }
+      fn2 ();
+      auto fn3 = [&...ty2 = ty, &i] () { if (sum (ty2...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn3 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn4 = [&...ty3 = ref (ty), &i] () { if (sum (ty3...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn4 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn5 = [=] () { if (sum (ty...) != i * 6 + 5) __builtin_abort (); };
+      fn5 ();
+      auto fn6 = [ty..., i] () { if (sum (ty...) != i * 6 + 5) __builtin_abort 
(); }; // { dg-warning "captured structured bindings are" "" { target 
c++17_down } }
+      fn6 ();
+      auto fn7 = [...ty2 = ty, i] () { if (sum (ty2...) != i * 6 + 5) 
__builtin_abort (); }; // { dg-warning "pack init-capture only available with" 
"" { target c++17_down } }
+      fn7 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn8 = [...ty3 = square (ty), i] () { if (sum (ty3...) != (i * 3 + 
2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) __builtin_abort (); }; // { 
dg-warning "pack init-capture only available with" "" { target c++17_down } }
+      fn8 ();                          // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn9 = [&] () { auto fn = [&] () { if (sum (ty...) != i * 6 + 5) 
__builtin_abort (); }; fn (); };
+      fn9 ();
+      auto fn10 = [&ty..., &i] () { auto fn = [&] () { if (sum (ty...) != i * 
6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured 
bindings are" "" { target c++17_down } }
+      fn10 ();
+      auto fn11 = [&] () { auto fn = [&...ty2 = ty, &i] () { if (sum (ty2...) 
!= i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack 
init-capture only available with" "" { target c++17_down } }
+      fn11 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn12 = [&ty..., &i] () { auto fn = [&...ty3 = ref (ty), &i] () { if 
(sum (ty3...) != i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning 
"pack init-capture only available with" "" { target c++17_down } }
+      fn12 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      auto fn13 = [=] () { auto fn = [=] () { if (sum (ty...) != i * 6 + 5) 
__builtin_abort (); }; fn (); };
+      fn13 ();
+      auto fn14 = [ty..., i] () { auto fn = [=] () { if (sum (ty...) != i * 6 
+ 5) __builtin_abort (); }; fn (); }; // { dg-warning "captured structured 
bindings are" "" { target c++17_down } }
+      fn14 ();
+      auto fn15 = [=] () { auto fn = [...ty2 = ty, i] () { if (sum (ty2...) != 
i * 6 + 5) __builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture 
only available with" "" { target c++17_down } }
+      fn15 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+      auto fn16 = [&ty..., &i] () { auto fn = [...ty3 = square (ty), i] () { 
if (sum (ty3...) != (i * 3 + 2) * (i * 3 + 2) + (i * 3 + 3) * (i * 3 + 3)) 
__builtin_abort (); }; fn (); }; // { dg-warning "pack init-capture only 
available with" "" { target c++17_down } }
+      fn16 ();                         // { dg-warning "lambda capture 
initializers only available with" "" { target c++11_only } .-1 }
+                                       // { dg-warning "captured structured 
bindings are" "" { target c++17_down } .-2 }
+      ++i;
+    }
+  i = 0;
+  for (auto [...tz] : t2)              // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (tz) == 3, "");
+      static_assert (same_type <decltype (tz...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (tz...[1]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (tz...[2]), short>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (sum (tz...) != i * 9 + 6)
+       __builtin_abort ();
+      auto fn = [=] () { if (sum (tz...) != i * 9 + 6) __builtin_abort (); };
+      fn ();
+      ++i;
+    }
+  if (auto [...tx [[maybe_unused]], ty] = t) // { dg-warning "structured 
bindings in conditions only available with" "" { target c++23_down } }
+    __builtin_abort ();
+  else
+    {
+      static_assert (sizeof... (tx) == 2, "");
+      static_assert (same_type <decltype (tx...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (tx...[1]), long long>::value, ""); 
// { dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (ty), short>::value, "");
+      if (sum (tx...) != 3 || ty != 3)
+       __builtin_abort ();
+    }
+  U a[3] = { 1, 2, 3 };
+  auto [aa, ab, ac] = a;       // { dg-warning "structured bindings only 
available with" "" { target c++14_down } }
+  static_assert (same_type <decltype (aa), int>::value, "");
+  static_assert (same_type <decltype (ab), int>::value, "");
+  static_assert (same_type <decltype (ac), int>::value, "");
+  auto [ad [[maybe_unused]], ...ae [[maybe_unused]]] = a; // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+                               // { dg-warning "structured bindings with 
attributed identifiers only available with" "" { target { c++17 && c++23_down } 
} .-2 }
+  static_assert (sizeof... (ae) == 2, "");
+  static_assert (same_type <decltype (ad), int>::value, "");
+  static_assert (same_type <decltype (ae...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ae...[1]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...af, ag] = a;                // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (af) == 2, "");
+  static_assert (same_type <decltype (af...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (af...[1]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ag), int>::value, "");
+  auto [ah, ai [[]], aj, ...ak [[]]] = a; // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+                               // { dg-warning "structured bindings with 
attributed identifiers only available with" "" { target { c++17 && c++23_down } 
} .-2 }
+  static_assert (sizeof... (ak) == 0, "");
+  static_assert (same_type <decltype (ah), int>::value, "");
+  static_assert (same_type <decltype (ai), int>::value, "");
+  static_assert (same_type <decltype (aj), int>::value, "");
+  auto [al, ...am [[]], an] = a;// { dg-warning "structured binding packs only 
available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+                               // { dg-warning "structured bindings with 
attributed identifiers only available with" "" { target { c++17 && c++23_down } 
} .-2 }
+  static_assert (sizeof... (am) == 1, "");
+  static_assert (same_type <decltype (al), int>::value, "");
+  static_assert (same_type <decltype (am...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (an), int>::value, "");
+  const auto &[...ao] = a;     // { dg-warning "structured binding packs only 
available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (ao) == 3, "");
+  static_assert (same_type <decltype (ao...[0]), const int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ao...[1]), const int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ao...[2]), const int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto &&[...ap, aq, ar [[]], as] = a;// { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+                               // { dg-warning "structured bindings with 
attributed identifiers only available with" "" { target { c++17 && c++23_down } 
} .-2 }
+  static_assert (sizeof... (ap) == 0, "");
+  static_assert (same_type <decltype (aq), int>::value, "");
+  static_assert (same_type <decltype (ar), int>::value, "");
+  static_assert (same_type <decltype (as), int>::value, "");
+  auto [at, ...au, av, aw] = a;        // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (au) == 0, "");
+  static_assert (same_type <decltype (at), int>::value, "");
+  static_assert (same_type <decltype (av), int>::value, "");
+  static_assert (same_type <decltype (aw), int>::value, "");
+  if (aa != 1 || ab != 2 || ac != 3
+      || ad != 1 || ae...[0] != 2 || ae...[1] != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || af...[0] != 1 || af...[1] != 2 || ag != 3     // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || ah != 1 || ai != 2 || aj != 3
+      || al != 1 || am...[0] != 2 || an != 3           // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || ao...[0] != 1 || ao...[1] != 2 || ao...[2] != 3// { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+      || aq != 1 || ar != 2 || as != 3
+      || at != 1 || av != 2 || aw != 3
+      || sum (ae...) != 5
+      || sum <decltype (ae)...> (ae...) != 5
+      || sum (square (square (ae))...) != 97
+      || sum (af...) != 3
+      || sum (ak...) != 0
+      || sum (am...) != 2
+      || sum (ao...) != 6
+      || sum <decltype (ao)...> (ao...) != 6
+      || sum (square (ao)...) != 14
+      || sum (ap...) != 0
+      || sum (au...) != 0
+      || (ae + ...) != 5               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + af) != 3               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + ak) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (am + ... + 0) != 2           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (ao + ...) != 6               // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (ap + ... + 0) != 0           // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + au) != 0)          // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+    __builtin_abort ();
+  return tos;
+}
+
+int
+main ()
+{
+  if (foo <S, T, int> () != 3)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp16.C 
b/gcc/testsuite/g++.dg/cpp26/decomp16.C
new file mode 100644
index 000000000000..548f9af0503f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp16.C
@@ -0,0 +1,240 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+int
+sum ()
+{
+  return 0;
+}
+
+template <typename T, typename ...A>
+T
+sum (T x, A... y)
+{
+  return x + sum (y...);
+}
+
+template <typename T>
+T
+square (T x)
+{
+  return x * x;
+}
+
+template <typename T, typename U>
+struct same_type { static const bool value = false; };
+
+template <typename T>
+struct same_type<T, T> { static const bool value = true; };
+
+typedef int V __attribute__((vector_size (16 * sizeof (int))));
+
+template <int N>
+void
+foo ()
+{
+  V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+  auto [...va] = v;                    // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (va) == 16, "");
+  static_assert (same_type <decltype (va...[5]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (va...[13]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [vb, ...vc, vd, ve] = v;                // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (vc) == 13, "");
+  static_assert (same_type <decltype (vb), int>::value, "");
+  static_assert (same_type <decltype (vc...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (vc...[12]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (vd), int>::value, "");
+  static_assert (same_type <decltype (ve), int>::value, "");
+  auto [vf, vg, vh, vi, ...vj] = v;    // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (vj) == 12, "");
+  static_assert (same_type <decltype (vf), int>::value, "");
+  static_assert (same_type <decltype (vg), int>::value, "");
+  static_assert (same_type <decltype (vh), int>::value, "");
+  static_assert (same_type <decltype (vi), int>::value, "");
+  static_assert (same_type <decltype (vj...[2]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (vj...[10]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  if (va...[13] != 14                  // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (va...) != 8 * 17
+      || sum (square (va)...) != 1496
+      || vb != 1
+      || vc...[10] != 12               // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (vc...) != 15 * 7 - 1
+      || sum <decltype (vc)...> (vc...) != 15 * 7 - 1
+      || vd != 15 || ve != 16
+      || vf != 1 || vg != 2 || vh != 3 || vi != 4
+      || sum (vj...) != 8 * 17 - 10
+      || (va + ...) != 8 * 17          // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + vc) != 15 * 7 - 1      // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + vj) != 8 * 17 - 10)        // { dg-warning 
"fold-expressions only available with" "" { target c++14_down } }
+    __builtin_abort ();
+  V v2[3] = { v, v + 1, v + 2 };
+  int i = 0;
+  for (auto [vk, ...vl, vm] : v2)      // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (vl) == 14, "");
+      static_assert (same_type <decltype (vk), int>::value, "");
+      static_assert (same_type <decltype (vl...[1]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (vl...[9]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (vm), int>::value, "");
+      if (vk != i + 1 || sum (vl...) != i * 14 + 15 * 8 - 1 || vm != i + 16)
+       __builtin_abort ();
+      ++i;
+    }
+  _Complex double c = 1.0 + 2.0i;
+  auto [...ca] = c;                    // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (ca) == 2, "");
+  static_assert (same_type <decltype (ca...[0]), double>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ca...[1]), double>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [cb, ...cc, cd] = c;            // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (cc) == 0, "");
+  static_assert (same_type <decltype (cb), double>::value, "");
+  static_assert (same_type <decltype (cd), double>::value, "");
+  auto [ce, ...cf] = c;                        // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (cf) == 1, "");
+  static_assert (same_type <decltype (ce), double>::value, "");
+  static_assert (same_type <decltype (cf...[0]), double>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...cg, ch] = c;                        // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (cg) == 1, "");
+  static_assert (same_type <decltype (cg...[0]), double>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ch), double>::value, "");
+  if (ca...[0] != 1.0 || ca...[1] != 2.0// { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (ca...) != 3.0
+      || sum <decltype (ca)...> (ca...) != 3.0
+      || sum (square (square (square (ca)))...) != 257.0
+      || cb != 1.0 || cd != 2.0
+      || ce != 1.0 || cf...[0] != 2.0  // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (cf...) != 2.0
+      || cg...[0] != 1.0 || ch != 2.0  // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (cg...) != 1.0
+      || (ca + ...) != 3.0             // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0.0 + ... + cc) != 0.0       // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + cf) != 2.0             // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (cg + ... + 0.0) != 1.0)      // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+    __builtin_abort ();
+  _Complex float c2[3] = { 1.0f + 2.0fi, 2.0f + 3.0fi, 3.0f + 4.0fi };
+  i = 0;
+  for (auto [...ci] : c2)              // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (ci) == 2, "");
+      static_assert (same_type <decltype (ci...[0]), float>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (ci...[1]), float>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (sum (ci...) != i * 2 + 3.0f)
+       __builtin_abort ();
+      ++i;
+    }
+}
+
+template <typename V, typename C, typename D>
+void
+bar ()
+{
+  V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+  auto [...va] = v;                    // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (va) == 16, "");
+  static_assert (same_type <decltype (va...[5]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (va...[13]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [vb, ...vc, vd, ve] = v;                // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (vc) == 13, "");
+  static_assert (same_type <decltype (vb), int>::value, "");
+  static_assert (same_type <decltype (vc...[0]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (vc...[12]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (vd), int>::value, "");
+  static_assert (same_type <decltype (ve), int>::value, "");
+  auto [vf, vg, vh, vi, ...vj] = v;    // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (vj) == 12, "");
+  static_assert (same_type <decltype (vf), int>::value, "");
+  static_assert (same_type <decltype (vg), int>::value, "");
+  static_assert (same_type <decltype (vh), int>::value, "");
+  static_assert (same_type <decltype (vi), int>::value, "");
+  static_assert (same_type <decltype (vj...[2]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (vj...[10]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  if (va...[13] != 14                  // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (va...) != 8 * 17
+      || vb != 1
+      || vc...[10] != 12               // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (vc...) != 15 * 7 - 1
+      || sum <decltype (vc)...> (vc...) != 15 * 7 - 1
+      || vd != 15 || ve != 16
+      || vf != 1 || vg != 2 || vh != 3 || vi != 4
+      || sum (vj...) != 8 * 17 - 10
+      || (va + ...) != 8 * 17          // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + vc) != 15 * 7 - 1      // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0 + ... + vj) != 8 * 17 - 10)        // { dg-warning 
"fold-expressions only available with" "" { target c++14_down } }
+    __builtin_abort ();
+  V v2[3] = { v, v + 1, v + 2 };
+  int i = 0;
+  for (auto [vk, ...vl, vm] : v2)      // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (vl) == 14, "");
+      static_assert (same_type <decltype (vk), int>::value, "");
+      static_assert (same_type <decltype (vl...[1]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (vl...[9]), int>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (vm), int>::value, "");
+      if (vk != i + 1 || sum (vl...) != i * 14 + 15 * 8 - 1 || vm != i + 16)
+       __builtin_abort ();
+      ++i;
+    }
+  C c = 1.0 + 2.0i;
+  auto [...ca] = c;                    // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (ca) == 2, "");
+  static_assert (same_type <decltype (ca...[0]), double>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ca...[1]), double>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [cb, ...cc, cd] = c;            // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (cc) == 0, "");
+  static_assert (same_type <decltype (cb), double>::value, "");
+  static_assert (same_type <decltype (cd), double>::value, "");
+  auto [ce, ...cf] = c;                        // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (cf) == 1, "");
+  static_assert (same_type <decltype (ce), double>::value, "");
+  static_assert (same_type <decltype (cf...[0]), double>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  auto [...cg, ch] = c;                        // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (cg) == 1, "");
+  static_assert (same_type <decltype (cg...[0]), double>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+  static_assert (same_type <decltype (ch), double>::value, "");
+  if (ca...[0] != 1.0 || ca...[1] != 2.0// { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (ca...) != 3.0
+      || sum <decltype (ca)...> (ca...) != 3.0
+      || cb != 1.0 || cd != 2.0
+      || ce != 1.0 || cf...[0] != 2.0  // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (cf...) != 2.0
+      || cg...[0] != 1.0 || ch != 2.0  // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+      || sum (cg...) != 1.0
+      || (ca + ...) != 3.0             // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (0.0 + ... + cc) != 0.0       // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (... + cf) != 2.0             // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+      || (cg + ... + 0.0) != 1.0)      // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+    __builtin_abort ();
+  D c2[3] = { 1.0f + 2.0fi, 2.0f + 3.0fi, 3.0f + 4.0fi };
+  i = 0;
+  for (auto [...ci] : c2)              // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+    {                                  // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+      static_assert (sizeof... (ci) == 2, "");
+      static_assert (same_type <decltype (ci...[0]), float>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      static_assert (same_type <decltype (ci...[1]), float>::value, ""); // { 
dg-warning "pack indexing only available with" "" { target c++23_down } }
+      if (sum (ci...) != i * 2 + 3.0f)
+       __builtin_abort ();
+      ++i;
+    }
+}
+
+int
+main ()
+{
+  foo <0> ();
+  bar <V, _Complex double, _Complex float> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp17.C 
b/gcc/testsuite/g++.dg/cpp26/decomp17.C
new file mode 100644
index 000000000000..49ad0e21f045
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp17.C
@@ -0,0 +1,28 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+typedef int V __attribute__((vector_size (16 * sizeof (int))));
+
+template <int N>
+void
+foo ()
+{
+  V v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
+  auto [va, vb, vc, vd, ...ve, vf, vg, vh, vi, vj, vk, vl, vm, vn, vo, vp, vq, 
vr] = v;
+                                       // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } .-1 }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-2 }
+                                       // { dg-error "18 names provided for 
structured binding" "" { target *-*-* } .-3 }
+                                       // { dg-message "while 
'__vector\\\(16\\\) int' decomposes into 16 elements" "" { target *-*-* } .-4 }
+  _Complex double c = 1.0 + 2.0i;
+  auto [...ca, cb, cc, cd] = c;                // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-error "4 names provided for 
structured binding" "" { target *-*-* } .-2 }
+                                       // { dg-message "while '__complex__ 
double' decomposes into 2 elements" "" { target *-*-* } .-3 }
+}
+
+int
+main ()
+{
+  foo <0> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp18.C 
b/gcc/testsuite/g++.dg/cpp26/decomp18.C
new file mode 100644
index 000000000000..86b9bf433223
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp18.C
@@ -0,0 +1,109 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+struct S { int a, b, c; };
+namespace std {
+  template <typename T> struct tuple_size;
+  template <int, typename> struct tuple_element;
+}
+struct T {
+  int a[3];
+  template <int I>
+  int &get () { return a[2 - I]; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <int N>
+struct std::tuple_element<N, T> { typedef int type; };
+
+template <int N>
+inline int
+foo ()
+{
+  static int a[4] = { N, N + 1, N + 2, N + 3 };
+  static auto [...aa] = a;             // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured binding 
declaration can be 'static' only in" "" { target c++17_down } .-2 }
+  aa...[1]++;                          // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+  return (... + aa);                   // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+bar ()
+{
+  static S s = { N, N + 1, N + 2 };
+  static auto [...sa] = s;             // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured binding 
declaration can be 'static' only in" "" { target c++17_down } .-2 }
+  sa...[1]++;                          // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+  return (sa + ...);                   // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+baz ()
+{
+  static T t = { { N, N + 1, N + 2 } };
+  static auto [ta, ...tb, tc, td] = t; // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured binding 
declaration can be 'static' only in" "" { target c++17_down } .-2 }
+  tc++;
+  return ((ta + tc + td) + ... + tb);  // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+qux ()
+{
+  thread_local int a[4] = { N, N + 1, N + 2, N + 3 };
+  thread_local auto [...aa] = a;       // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured binding 
declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+  aa...[1]++;                          // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+  return (... + aa);                   // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+freddy ()
+{
+  thread_local S s = { N, N + 1, N + 2 };
+  thread_local auto [...sa] = s;       // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured binding 
declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+  sa...[1]++;                          // { dg-warning "pack indexing only 
available with" "" { target c++23_down } }
+  return (sa + ...);                   // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+}
+
+template <int N>
+inline int
+corge ()
+{
+  thread_local T t = { { N, N + 1, N + 2 } };
+  thread_local auto [ta, ...tb, tc, td] = t;   // { dg-warning "structured 
binding packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured binding 
declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+  tc++;
+  return ((ta + tc + td) + ... + tb);  // { dg-warning "fold-expressions only 
available with" "" { target c++14_down } }
+}
+
+int
+main ()
+{
+  if (foo <2> () != 15 || foo <2> () != 16 || foo <2> () != 17
+      || foo <42> () != 175 || foo <42> () != 176
+      || bar <5> () != 19 || bar <5> () != 20 || bar <5> () != 21
+      || bar <18> () != 58 || bar <18> () != 59
+      || baz <3> () != 13 || baz <3> () != 14 || baz <3> () != 15
+      || baz <22> () != 70 || baz <22> () != 71)
+    __builtin_abort ();
+  if (qux <2> () != 15 || qux <2> () != 16 || qux <2> () != 17
+      || qux <42> () != 175 || qux <42> () != 176
+      || freddy <5> () != 19 || freddy <5> () != 20 || freddy <5> () != 21
+      || freddy <18> () != 58 || freddy <18> () != 59
+      || corge <3> () != 13 || corge <3> () != 14 || corge <3> () != 15
+      || corge <22> () != 70 || corge <22> () != 71)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp19.C 
b/gcc/testsuite/g++.dg/cpp26/decomp19.C
new file mode 100644
index 000000000000..b4d97a154560
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp19.C
@@ -0,0 +1,46 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+namespace std {
+  template <typename T> struct tuple_size;
+  template <int, typename> struct tuple_element;
+}
+struct T {
+  int a[3];
+  template <int I>
+  int &get () { return a[2 - I]; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 3; };
+template <int N>
+struct std::tuple_element<N, T> { typedef int type; };
+
+template <int N>
+inline void
+foo ()
+{
+  static T t = { { N, N + 1, N + 2 } };
+  static auto [ta, ...tb, tc] = t;     // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured binding 
declaration can be 'static' only in" "" { target c++17_down } .-2 }
+                                       // { dg-message "mangling of structured 
binding pack elements not implemented yet" "" { target *-*-* } .-3 }
+}
+
+template <int N>
+inline void
+bar ()
+{
+  thread_local T t = { { N, N + 1, N + 2 } };
+  thread_local auto [...ta] = t;       // { dg-warning "structured binding 
packs only available with" "" { target { c++17 && c++23_down } } }
+                                       // { dg-warning "structured bindings 
only available with" "" { target c++14_down } .-1 }
+                                       // { dg-warning "structured binding 
declaration can be 'thread_local' only in" "" { target c++17_down } .-2 }
+                                       // { dg-message "mangling of structured 
binding pack elements not implemented yet" "" { target *-*-* } .-3 }
+}
+
+int
+main ()
+{
+  foo <0> ();
+  bar <0> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp20.C 
b/gcc/testsuite/g++.dg/cpp26/decomp20.C
new file mode 100644
index 000000000000..5091e1367814
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp20.C
@@ -0,0 +1,53 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct S {
+  explicit operator bool () const noexcept { return true; }
+};
+namespace std {
+  template <typename T> struct tuple_size;
+  template <int, typename> struct tuple_element;
+}
+int x;
+struct T {
+  template <int I>
+  int &get () { return x; }
+  explicit operator bool () const noexcept { return false; }
+};
+template <>
+struct std::tuple_size<T> { static constexpr int value = 0; };
+template <int N>
+struct std::tuple_element<N, T> { typedef int type; };
+
+template <int N>
+void
+foo ()
+{
+  int a[0] = {};
+  auto [...aa] = a;            // { dg-warning "structured binding packs only 
available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (aa) == 0, "");
+  S s = {};
+  auto [...sa] = s;            // { dg-warning "structured binding packs only 
available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (sa) == 0, "");
+  T t = {};
+  auto [...ta] = t;            // { dg-warning "structured binding packs only 
available with" "" { target { c++17 && c++23_down } } }
+                               // { dg-warning "structured bindings only 
available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (ta) == 0, "");
+  if (auto [...sb] = s)                // { dg-warning "structured bindings in 
conditions only available with" "" { target c++23_down } }
+    static_assert (sizeof... (sb) == 0, "");
+  else
+    __builtin_abort ();
+  if (auto [...tb] = t)                // { dg-warning "structured bindings in 
conditions only available with" "" { target c++23_down } }
+    __builtin_abort ();
+  else
+    static_assert (sizeof... (tb) == 0, "");
+}
+
+int
+main ()
+{
+  foo <0> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/decomp21.C 
b/gcc/testsuite/g++.dg/cpp26/decomp21.C
new file mode 100644
index 000000000000..6baa8aac9c5b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp26/decomp21.C
@@ -0,0 +1,103 @@
+// P1061R10 - Structured Bindings can introduce a Pack
+// { dg-do run { target c++11 } }
+// { dg-options "" }
+
+using size_t = decltype (sizeof 0);
+
+auto g () -> int (&)[4]
+{
+  static int a[4] = { 1, 2, 3, 4 };
+  return a;
+}
+
+template <size_t N>
+void
+h (int (&arr)[N])
+{
+  auto [a, ...b, c] = arr;                             // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                                       // { dg-warning 
"structured bindings only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (b) == 2, "");
+  auto &[f, ...g, h] = arr;                            // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                                       // { dg-warning 
"structured bindings only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (g) == 2, "");
+  if (&f != &arr[0] || &h != &arr[3]
+      || &g...[0] != &arr[1] || &g...[1] != &arr[2])   // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+    __builtin_abort ();
+  auto &[...e] = arr;                                  // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                                       // { dg-warning 
"structured bindings only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof ... (e) == 4, "");
+  if (&e...[0] != &arr[0] || &e...[3] != &arr[3])      // { dg-warning "pack 
indexing only available with" "" { target c++23_down } }
+    __builtin_abort ();
+}
+
+struct C { int x, y, z; };
+
+template <class T>
+void
+now_i_know_my ()
+{
+  auto [a, b, c] = C ();                               // { dg-warning 
"structured bindings only available with" "" { target c++14_down } }
+  auto [d, ...e] = C ();                               // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                                       // { dg-warning 
"structured bindings only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (e) == 2, "");
+  auto [...f, g] = C ();                               // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                                       // { dg-warning 
"structured bindings only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (f) == 2, "");
+  auto [h, i, j, ...k] = C ();                         // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                                       // { dg-warning 
"structured bindings only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (k) == 0, "");
+//  auto [l, m, n, o, ...p] = C ();
+}
+
+auto foo () -> int (&)[2]
+{
+  static int a[2] = { 1, 2 };
+  return a;
+}
+
+template <class T>
+void
+bar ()
+{
+  auto [...a] = foo ();                                        // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                                       // { dg-warning 
"structured bindings only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (a) == 2, "");
+  auto [b, c, ...d] = foo ();                          // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                                       // { dg-warning 
"structured bindings only available with" "" { target c++14_down } .-1 }
+  static_assert (sizeof... (d) == 0, "");
+}
+
+struct D { };
+
+void
+baz (...)
+{
+  __builtin_abort ();
+}
+
+template <typename T>
+void
+qux ()
+{
+  D arr[1] = {};
+  auto [...e] = arr;                                   // { dg-warning 
"structured binding packs only available with" "" { target { c++17 && 
c++23_down } } }
+                                                       // { dg-warning 
"structured bindings only available with" "" { target c++14_down } .-1 }
+  baz (e...);
+}
+
+int d;
+
+void
+baz (D)
+{
+  d = 1;
+}
+
+int
+main ()
+{
+  h (g ());
+  now_i_know_my <int> ();
+  bar <int> ();
+  qux <int> ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C 
b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
index cfc5f6177a35..9284bc22c1a1 100644
--- a/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
+++ b/gcc/testsuite/g++.dg/cpp26/feat-cxx26.C
@@ -395,8 +395,8 @@
 
 #ifndef __cpp_structured_bindings
 #  error "__cpp_structured_bindings"
-#elif __cpp_structured_bindings != 202403
-#  error "__cpp_structured_bindings != 202403"
+#elif __cpp_structured_bindings != 202411
+#  error "__cpp_structured_bindings != 202411"
 #endif
 
 #ifndef __cpp_template_template_args

Reply via email to