https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124456

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |ppalka at gcc dot gnu.org

--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The problem is that when the structured bindings initializer is type dependent,
we really don't know how many elements or which ones the structured binding
pack has.
When cp_finish_decomp is called with a type dependent structured bindings,
DECL_VALUE_EXPR of each of the structured binding and the pack is set to
ARRAY_REF of the base and corresponding index.  Only when cp_finish_decomp is
called on non-type dependent one it can actually figure everything up and then
DECL_VALUE_EXPR of the
structured binding pack is a TREE_VEC with the individual elements of the pack
etc.

I've tried:
--- gcc/cp/pt.cc.jj     2026-03-12 08:48:04.747569066 +0100
+++ gcc/cp/pt.cc        2026-03-12 09:48:43.698506293 +0100
@@ -14135,6 +14135,15 @@ tsubst_pack_expansion (tree t, tree args
            return error_mark_node;
          gcc_assert (DECL_HAS_VALUE_EXPR_P (orig_arg));
          arg_pack = DECL_VALUE_EXPR (orig_arg);
+         if (TREE_CODE (arg_pack) == ARRAY_REF)
+           {
+             /* If the structured binding pack has type dependent
+                base, we can't expand it yet.  */
+             tree base = TREE_OPERAND (arg_pack, 0);
+             gcc_assert (VAR_P (base)
+                         && type_dependent_expression_p (base));
+             return t;
+           }
          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),
and while it fixes the ICE on the above testcase, when I try to actually
instantiate the lambda, I get an ICE again.

So I'm afraid I'm stuck.

// PR c++/124456

struct A { int i; };

A
foo (auto...)
{
  return A ();
}

void
bar (auto...)
{
}

auto
baz (auto... t)
{
  return [=] (auto... a) { auto [... k] = foo (t..., a...); return bar (k...);
};
}

auto x = baz (1);
auto y = x (1, 2, 3);

Reply via email to