c++: Fix structured binding pack instantiation ICE [PR125591]

The following testcase ICEs in tsubst_pack_expansion, we trigger the
gcc_assert (DECL_DECOMPOSITION_P (orig_arg));
assertion.  But in this case, retrieve_local_specialization doesn't
return the expected DECL_DECOMPOSITION_P, but ARGUMENT_PACK_SELECT instead.
That is because it has been registered earlier in
gen_elem_of_pack_expansion_instantiation
in
              aps = make_argument_pack_select (arg_pack, index);
              if (!mark_used (parm, complain) && !(complain & tf_error))
                return error_mark_node;
              register_local_specialization (aps, parm);
The following patch just stops assuming retrieve_local_specialization
has to return DECL_DECOMPOSITION_P, but allows also ARGUMENT_PACK_SELECT.
The patch is large due to reindentation, with diff -upb it is just

@@ -14309,8 +14309,9 @@ tsubst_pack_expansion (tree t, tree args
       else if (DECL_DECOMPOSITION_P (parm_pack))
        {
          orig_arg = retrieve_local_specialization (parm_pack);
+         if (DECL_DECOMPOSITION_P (orig_arg))
+           {
        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));
@@ -14339,6 +14340,12 @@ tsubst_pack_expansion (tree t, tree args
            }
        }
       else
+           {
+             gcc_assert (TREE_CODE (orig_arg) == ARGUMENT_PACK_SELECT);
+             arg_pack = orig_arg;
+           }
+       }
+      else
         {
          int idx;
           template_parm_level_and_index (parm_pack, &level, &idx);

2026-08-06  Jakub Jelinek  <jakub@redhat.com>

	PR c++/125591
	* pt.cc (tsubst_pack_expansion): Don't require
	retrieve_local_specialization on structured binding to
	always return structured binding, instead handle if it returns
	ARGUMENT_PACK_SELECT.

	* g++.dg/cpp26/decomp31.C: New test.

Reviewed-by: Jason Merrill <jason@redhat.com>
2 files changed