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

commit r16-7427-gbf2657d9d45e50c4eb82da3f6f8d9d26e288890f
Author: Patrick Palka <[email protected]>
Date:   Mon Feb 9 20:32:39 2026 -0500

    c++: tf_partial and alias_ctad_tweaks [PR122621]
    
    Like in r15-6740-g27d620d6769715 for instantiate_template with dependent
    arguments, we also need to set tf_partial during the alias_ctad_tweaks
    transformation mainly for benefit of properly handling extra-args trees.
    
    In this testcase during alias_ctad_tweaks we substitute the dependent
    ElemTs={Tuple<Us...>}, Ts={Ts...} into the requires-clause, which
    tsubst_pack_expansion decides to defer via extra-args, and for the
    subsequent add_extra_args (during guide overload resolution) to merge
    the deferred dependent arguments correctly, tf_partial has to have been
    set.
    
            PR c++/122621
    
    gcc/cp/ChangeLog:
    
            * pt.cc (tsubst_pack_expansion): Use tf_partial instead of
            tf_none, except when substituting outer (non-dependent) template
            arguments.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/class-deduction-alias26.C: New test.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/cp/pt.cc                                         |  5 +++--
 gcc/testsuite/g++.dg/cpp2a/class-deduction-alias26.C | 17 +++++++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 049bbf07e015..7c6577b48eff 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -31718,7 +31718,7 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
                          (INNERMOST_TEMPLATE_PARMS (fullatparms)));
     }
 
-  tsubst_flags_t complain = tf_none;
+  tsubst_flags_t complain = tf_partial;
   tree aguides = NULL_TREE;
   tree atparms = INNERMOST_TEMPLATE_PARMS (fullatparms);
   unsigned natparms = TREE_VEC_LENGTH (atparms);
@@ -31825,7 +31825,8 @@ alias_ctad_tweaks (tree tmpl, tree uguides)
          if (ci)
            {
              if (tree outer_targs = outer_template_args (f))
-               ci = tsubst_constraint_info (ci, outer_targs, complain, 
in_decl);
+               ci = tsubst_constraint_info (ci, outer_targs,
+                                            complain & ~tf_partial, in_decl);
              ci = tsubst_constraint_info (ci, targs, complain, in_decl);
            }
          if (ci == error_mark_node)
diff --git a/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias26.C 
b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias26.C
new file mode 100644
index 000000000000..01fd1a4d5e25
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/class-deduction-alias26.C
@@ -0,0 +1,17 @@
+// PR c++/122621
+// { dg-do compile { target c++20 } }
+
+template <class, class>
+concept constructible_from = true;
+
+template <class... ElemTs>
+struct Tuple {
+    template <class... Ts> requires (... && constructible_from<ElemTs, Ts>)
+    Tuple(Ts &&...) {}
+};
+
+template <class... Us>
+using A = Tuple<Tuple<Us...>>;
+
+using type = decltype(A{0});
+using type = Tuple<Tuple<>>;

Reply via email to